I have started working with a large code base, and a lot of the code has been set up with a strange format for functions. more or less every function has the following format
foo(){
trace_messages()
// this is what I don't get
try{
// all code goes here
} finally {
trace_messages()
}
}
I can't see any sense behind the insistence on wrapping more or less the entire work of function in a try. Is this some sort of 'best practice' that I never got told about?
EDIT:
perhaps I should have stated, but the two calls to trace_messages() are actually different sections of code, but more or less the same... if you follow my meaning
The intention of that code was to make sure that trace_messages() was guaranteed to executed in the beginning and before the end of foo().
finally is guaranteed to execute both in case everything runs fine, and if the code inside try fails miserably with some nasty uncaught runtime exception.
I agree that the format chosen to achieve this intention is not of the best, normally that is done with some sort of AOP, in Spring you would wrap foo() into Around advice.
Find the definition of trace_messages(), and you will see what the last guy was trying to do. If you are using an IDE like Eclipse, right-click on trace_messages() and there should be an option to jump directly to the definition.
Related
In the getUsers method, it invokes an RestTemplate with remote api service. In the code, I want to mock that it throws exception. Then I hard code with throw new Exception("read failed").
I know that the code below 'throws' will not be reachable. But I guess this should be only a warning in Intellij idea as the same as VisualStuido does with C#. But here it is an compile error.
Is there any way to suppress this compile error? Because I want to mock an exception here. Thanks.
Edit:
Thanks all you guys! Yes, I am trying to insert some temporary debug code, not production code. I will remove the "throws" code once my debug is done.
Yes, unreachable code is a compilation error in Java, not just a warning. The code inspection does not "look" into conditionals, so you can simply do the following:
if (true)
throw new MyException();
No because it's compiler error - use dummy condition like
if(true) {
throw new Exception("read failed");
}
but also consider mocking this method using Mockito or some dummy mock implementation - you will be able then to create proper unit test - such "testing" is rather bad idea and will not help you in the future (just imagine adding such lines every time you will change something and need to test again)
Is there any way to suppress this compile error?
No. You can remove these 7 lines or comment them out. An exception is thrown unconditionally so there is no way the code below will ever be executed.
I am strongly against introducing a dummy condition to trick the compiler. You can fool the compiler, but you can't fool the developers that will be maintaining the codebase after you.
Misconception: it is an error, and that is simply what the Java language spec wants it to be, see here:
It is a compile-time error if a statement cannot be executed because it is unreachable.
And you are going down the wrong rabbit hole: you shouldn't try to work around this "warning". When your production code has to throw that exception, then there is zero sense in having other code follow that throws statement in your production code.
If you want to do some sort of mocking, all of that should happen in your "test" code base.
In other words: to enable yourself to test that catch block, what you could do: extract the part in the try block in a class of its own. Then pass a mocked instance of that class to your production code, and have that mock throw when calling a method on it.
Sometimes it is pragmatic to make slight changes to production code for testability (for example to make methods not private, to allow for access in the same package for test code). But your idea goes way beyond that. So: don't waste your time working around the error.
What is the possible usage of ZuulFilter.run() return value?
All the examples (for instance Spring example) return null.
The official documentation says:
Some arbitrary artifact may be returned. Current implementation ignores it.
So why to have it at all?
I've used this lib in multiple projects and I never thought to look into and stumbled upon this question so I had to look. Just tracing the code in IntelliJ, it does look like the results are pointless.
I'm on zuul-core:1.3.1:
Looking at FilterProcessor, when the routing methods are called to route based on the type, they all call runFilters(sType) which ultimately get the the return Object in question of the implementing IZuulFilter classes. The trail seems to stop here.
I then stopped to looked at their test classes and nothing seems to do anything with the return Object either nor the ZuulFilterResult that wraps it.
I then thought, ok, well maybe there is a way to pass data from one IZuulFilter to another (e.g. from pre to route) but that doesn't seem possible either since FilterProcessor.processZuulFilter(ZuulFilter) doesn't do anything with the results and just passes it back to runFilters(sType) which we know ignores it.
My next line of questioning was, "well, perhaps you can provide your own FilterProcessor implementation and swap it out and actually use the Object somewhere". But alas, it looks like that isn't the case either unless you want/need to implement a lot more even into the ZuulServlet?
Lastly, I thought, "well, maybe it's just a convention thing". But java.lang.Runnable.run() is void and javax.servlet.Filter.doFilter is also void.
So for now, my best guess is that like all of us at some point in our careers, we sometimes fall into a YAGNI situation; perhaps this is just one example.
I know how to make sure that a function has been invoked, using:
mockito.verify
now, I want to make sure that on every path of the function (every 'if', 'if else' and 'else') - the function was invoked.
I can basically write unit test for every case, but I want to make sure that if any further cases will be added - there will also be invocation to that method.
Unit testing alone will not do that. You have to look into using coverage in order to get there.
Unit testing can only tell you if the paths that were taken resulted in a "valid" result; but there is no knowledge of "all paths" that exist; and if they were all hit.
So you want to turn here for example and learn which coverage tool would work for you.
When you are working with eclipse or intellij, those things work out of the box; you can install plugins like cobertura or eclemma within eclipse; and then do a "run unit test with coverage".
But of course: that only results in a number. You then have to look carefully at your code to understand if you are happy with that number (where those IDEs make that really easy; they can show you your source code, and which paths were taken).
Meaning: coverage is a whole concept, and you have to understand what that means; and in which way you can make that concept helpful for your daily work. For example, you the last thing you want is your boss giving you a specific target goal for coverage.
And just to be sure: there is no tooling that tells you: you added new code, and now this specific method invocation is no longer coming through all parts. What coverage gives you is that you had 75.32% coverage before your change; and afterwards, it went down to 74.01% ... the rest is then up to you.
now, I want to make sure that on every path of the function (every 'if', 'if else' and 'else') - the function was invoked.
You don't want that.
The misunderstanding is that you don't test "the code". You test public observable behavior. In your case the behavior is that your unit under test (UuT) (after doing other stuff) calls a method on a dependency (I hope).
You don't want to test "the code" because it may change for becoming cleaner and/or support more behavior. But then you don't want to change your existing tests since they will guarantee that the desired behavior is preserved during your refactoring.
On the other hand each test method should verify exactly one expectation about the UuTs behavior. This means that you should already have one test method for each execution path though your if/else cascade. So all you have to do is to add the verify() instruction to each of this test methods.
Finally you may have an easier job testing your code if you force Single Layer of Abstraction principle which basically says that a method either calls methods on some dependencies (aka "dispatching"), calls internal methods or does low level operations. This principle may lead to a design, where the "low level" stuff your UuT currently does moves to a new dependency so that your UuT only needs to do two calls on some dependencies in a certain order...
I have encountered this issue before where I needed to tightly test bound the switch cases, and I was desperate enough to do that.
I am asuming test coverage analysis is not enough for you. For me, the if-else conditions part was so critical that changing something unintentionally could have proved greatly disastrous, so I could not afford to leave a failure prone code and I needed a test case to satisfy myself.
How I satisfied myself is here:
1: Changed the conditions such as if..else, etc to a swich case variable - TaskSwitcherEnum, say taskSwitcher, and performed all sorts of operations under various possible values of TaskSwitcherEnum.
switch (taskSwitcher){
case TaskSwitcherEnum.Task_Type_1:
//do Something before break
break;
case TaskSwitcherEnum.Task_Type_2:
//do Something again
break;
...
}
2: Tightly tested the desired method for all possible values of taskSwitcherEnum. Mockito.verify(), whether required task method is called once, for each given TaskSwitcherEnum value.
3: Finally did a junit like this:
assertEquals("Task performance strategy is designed to handle only five cases.", 5, taskSwitcherEnum.values().length);
Doing this made sure [at least test covered] following things:
1: That my code has only desired branches, and any other code branch addition/deletion is caught by a test case.
2: That each branch does it's desired job by calling a method that I want, through testing on every particular Enum values against a called method.
Gist of the whole answer is, sometimes a little design change helps a lot.
Suppose I have a class called Foo. This class will be modified by many people, and WILL print information to the console. To this effect, we have the following method:
private void print(String message){ ... }
which prints out to the screen in the format we want.
However, while reviewing code from other devs I see that they constantly call System.out.println(...)
instead, which results in barely-readable printouts.
My question is the following: is it possible to prevent any and every use of System.out.println() in Foo.java? If so, how?
I've tried looking this up, but all I found had to do with inheritance, which is not related to my question.
Thanks a lot!
N.S.
EDIT: I know that whatever I have to do to prevent the use of a method could be removed by a dev, but we have as a policy never to remove code marked //IMPORTANT so it could still be used as a deterrent.
EDIT2: I know I can simply tell the devs not to do it or use code reviews to filter the "errors" out but 1) I'm already doing it and it costs a lot of time and 2) the question is whether this is possible or not, NOT how to deal with my devs.
public methods are just that - public. There is no way to restrict access to them.
This kind of problem is usually "solved" by setting up some code-checker like PMD or checkstyle and integrating them into the continuous integration build. So violations of these stuff will be emailed to someone with a big hammer :-)
Although communicating that developers should not use System.out directly would be preferred, you could set System.out to another PrintStream, then use the alternative PrintStream in the private method. That way, when people use System.out.println they won't output anything but you'll still be able to use the alternative PrintStream... something like they do here: http://halyph.blogspot.com/2011/07/how-to-disable-systemout.html
Pre-commit hooks for your revision control system (SVN, Git, Mercurial) can grep for uses of System.{err,out} and prevent commit if they occur.
http://stuporglue.org/svn-pre-commit-hook-which-can-syntax-check-all-files/ is an example that takes an action for different changed files based on file extension for SVN. You should be able to modify that example to take an example based on some subset of Java files and reject if something like the following is true
egrep -q '\bSystem\.(err|out)\b'
You can redirect System.out calls to a streams that ignores the output or that redirects it to your logging system.
System.setOut(printStream);
You can also kill those using System.out.println in a production environment.
You can replace the OutputStream of System with your own implementation that would either throw an exception, or redirect the call to your own print implementation (which you would need to make public).
No, it's not possible to 100% prevent a class from ever using a specific method in Java.
Having that said...
My suggestion would be to add code analysis to your build process and failing the build on any occurrence of System.out.println. A good place to start if you're interested in going this route would be to check out PMD.
Also... have some constructive discussions with your developers and talk about why they're doing what they're doing. Good luck.
i need to know which methods were invoked one by one in code. Simple step-by-step debugging doesn't help (need too much time). How can i do this? It would be really great do this without changes of code and saving result in file.
Since it seems that maybe you don't want to check the stack tree, just the order, you could check out BTrace or Adding logging with Java agent.
Before your program finishes, you could Thread.currentThread().getStackTrace(); and then print each of those elements. A stack trace shows you the order of execution in your thread.
Sounds like a cross-cutting concern, especially when you talk about not changing existing code.
AspectJ is available to do this work for you using pointcuts.
http://www.eclipse.org/aspectj/doc/released/progguide/starting-aspectj.html
Do you mean you want to log every method call that occurs in your program? If so, have a look at AspectJ - there's an example here which logs particular methods, but you can easily adapt it to cover all methods.
What about when you catch a Exception you can try to use printStackTrace() function to dump out what has been invoked.
try{
//Your code
}
catch(Exception e){
e.printStackTrace();
}
Run your code in debug mode, you'll be able to set breakpoints to pause the execution, proceed line by line, inspect variables, etc.. Basically all the IDEs have debug mode.