I have a method in java class file like
public void SIMPLE_METHOD(some params){
...code here...
}
Is there annotation I can use above this method so, a method will be ran before SIMPLE_METHOD, if that pre-method returns true this SIMPLE_METHOD will run other wise this method will be ignored and control will be shifted to next execution point.
I guess the best way to do something like that in your case (since you're already using spring) is to use Spring AOP and #Around advice.
See 6.2.4.5. Around advice:
Around advice runs "around" a matched method execution. It has the
opportunity to do work both before and after the method executes, and
to determine when, how, and even if, the method actually gets to
execute at all.
UPDATE: Also, if you need this for implementing cache on method call it might be a good idea to take a look on Cache Abstraction and #Cacheable.
Related
I'm making a small project and I'm currently stuck on a way to achieve one of the capabilities I need.
Basically I want a method to execute when I'm calling an annotated method.For example
#PrintAnnotation
public void print(){
System.out.println("inside method");
The print annotation would just print extra test, so on calling the above method I would like to get
"Used print annotation"
"Inside method"
That's all.
I'm looking into the annotation processor API but there is no documentation anywhere except reading the javadoc which is crazy, and if I understand correctly its compile only so you cant change the original classes, only add.
I also found answers suggesting to use reflection, but to use reflection I need code triggered that checks if the method is annotated, but to do that I have to add an extra method to every method in the program, like
public void print(){
checkAnnotation();
System.out.println("test");
}
But I need it to work with only adding the annotation, not hundreds of one lines in every method of every class.
It is not possible through "only annotation" with no third party libraries and no custom code.
Annotation is only an annotation and nothing else.
It means you have to have those print and checkAnnotation methods which will detect presence of your Annotation on desired Target (Class,Method, Field...) and do what you'd like to. System.out.println("test"); definitely will not do that.
If you go with those print and checkAnnotation methods - create an utility with those methods and call print from anywhere instead of System.out.println.
But actually, what you try to achieve is about AOP. Your custom annotation can be used with it.
Then, you tagged question with spring tag, do you use Spring? It is a set of third party libraries and has AOP.
I want to ask more of a conceptual question related to testing. I am using Mockitos for my unit testing.
I have a method that does bunch of things. All the methods it calls internally are void methods, which in turn will do some other actions. The method under question can complete with exception or without exception. There is no scope for writing assert statements as it mostly calls void methods. Also, I have written independent unit test for all other methods of this class.
My question is if I need test coverage, I should write test case for all methods. But, I do not find any valid assert for one of my method. The method under question is an important method from unit test coverage perspective. When I run my test, I do see in logs that the methods executes fine but there is really nothing to assert. What should I do in such a situation?
1) Leave the method as is without any asserts? It still is checking if everything is working as expected
2) Create 2 methods one that expects exception ( Negative Testcase) and one regular test method with no asserts. ( This is to basically show I have covered both positive and negetive scenario). I still do not have any asserts here.
Is this the right approach to take or there is a better way for dealing with this problem?
If you don't have anything worth asserting, you can try verification instead.
verify(someMock, times(x)).someMethod();
More on verification with Mockito in the documentation: https://mockito.googlecode.com/hg-history/1.5/javadoc/org/mockito/Mockito.html
Why isn't there anything to assert? Let A be the universe if you run your method. Let B be the universe if you don't run your method. If A == B then stop calling the method, it's not doing anything. If A != B then assert that whatever is different about them is true.
i.e., what is your method actually doing? That should be part of your test.
I would like to verify some things using Mockito but studying the documentation has lead me to believe that it's not possible without going outside the usual Mockito tools. Take this for an example:
DrawTool tool = mock(DrawTool.class);
new Drawer().draw(tool);
verify(tool).begin(); // Make sure begin and end are called exactly once each
verify(tool).end();
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();
inOrder.verifyNoMoreInteractions();
This test verifies several things well, such as verifying that flush is the last interaction, but it seems that Mockito has no way to verify that begin is the first interaction. I'm surprised by that asymmetry in Mockito's tools and so I'm investigating the possibility of creating custom VerificationModes. I'd like to create a VerificationMode called something like beforeAnyOther and use it like this:
inOrder.verify(tool, beforeAnyOther()).begin();
inOrder.verify(tool).end();
inOrder.verify(tool, beforeAnyOther()).flush();
inOrder.verifyNoMoreInteractions();
The intent would be to verify that begin is called first and that there are no relevant interactions between end and flush while leaving the interactions between begin and end unspecified.
I have been studying the source code for the existing VerificationModes and it seems that in principle this should be a simple VerificationMode to implement, but once I get beyond a few of Mockito's major classes the documentation becomes very thin, almost like it's trying to tell me that I shouldn't be touching these classes. I'm especially wary of the packages that start org.mockito.internal because a name like that suggests to me that these classes are subject to change even though they are public.
The really important classes for implementing a VerificationMode seem to be all in the org.mockito.internal.verification.api package. That entire package seems to have only one bit of javadoc, and it says, "This package should be open to public once verification API is fully finished." Does that mean that this package is being actively modified and so I shouldn't use anything it contains, or is that just something that it has said for years and the package will probably never actually change?
If I can't use the classes in org.mockito.internal.verification.api then it seems it is impossible to implement custom VerificationModes. Is there a way to do things like this without custom VerificationModes?
If you can fully specify the sequence of calls that will happen on your mock, then you won't need a beforeAnyOther verification mode. For example, assuming your desired behavior is...
begin gets called once, then
end gets called once, then
flush gets called once
no other calls are made on tool
then the following should the job:
// Verify that the three invocations arrived in the desired order.
InOrder inOrder = inOrder(tool);
inOrder.verify(tool).begin();
inOrder.verify(tool).end();
inOrder.verify(tool).flush();
// Verify that the three invocations are all we received.
Mockito.verify(tool).begin();
Mockito.verify(tool).end();
Mockito.verify(tool).flush();
Mockito.verifyNoMoreInteractions();
On the other hand, if you have any additional calls that happen outside of the sequence you wish to verify then you're correct, Mockito can't verify that at present. So for example, if you knew you had to call tool.setPenColor() at some point between begin and flush but it didn't matter if this call came before or after the call to end, you'd be out of luck.
You can handle this situation in some other mocking libraries. EasyMock makes this easiest - for example, for a sequence where begin comes first, flush comes last, and we don't care about the calls in the middle:
DrawTool mock = EasyMock.createMock(DrawTool.class);
EasyMock.checkOrder(mock, true);
mock.begin();
EasyMock.expectLastCall();
EasyMock.checkOrder(mock, false);
mock.end();
EasyMock.expectLastCall();
EasyMock.expect(mock.someOtherCallThatReturnsAValue()).andReturn(null);
EasyMock.checkOrder(mock, true);
mock.flush();
EasyMock.expectLastCall();
EasyMock.replay(mock);
new Drawer().draw(tool);
EasyMock.verify(mock);
An equivalent test appears to be possible, if unwieldy, in JMock 2. It's a bit easier in JMock 1, but that library is antiquated (circa JDK 1.3), so don't use it. This isn't possible in Moxie (disclaimer/shameless plug: I'm the author), but there's now a todo list item for that.
I can't speak for the Mockito devs as to why the Mockito verification API docs are the way they are - best ask them on the mailing list. I'm sure they'd welcome a patch.
I'm testing a function that takes several paramters and on the basis of their values calls different private methods.
I want to check that the function always call the right private method.
Since I know what the private methods will do I can check the final result but it would be more convenient to be able to check directly if the right function was called, because I have already tested the private methods.
Is there a way to replace a privae method with a stub?
Yes, there are mocking libraries that let you do this. One is PowerMock. From their private method tutorial, you need something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyUnit.class)
public class TestMyUnit {
#Test
public void testSomething() {
MyUnit unit = PowerMock.createPartialMock(MyUnit.class, "methodNameToStub");
PowerMock.expectPrivate(unit, "methodNameToStub", param1).andReturn(retVal);
EasyMock.replay(unit);
unit.publicMethod(param1);
EasyMock.verify(unit);
}
}
However, I really disagree with this practice myself. Your unit test should test inputs, outputs, and side effects, and that's it. By ensuring that a private method is called correctly, all you're doing is preventing your code from being easily refactored.
In other words, what if down the road you want to change how your unit does its job? The safe way to do this is to make sure the code is under (passing) tests, then refactor the code (potentially including changing which internal methods are called), and then run the tests again to make sure you didn't break anything. With your approach, this is impossible because your tests test the exact implementation, not the behaviour of the unit itself. Refactoring will almost always break the test, so how much benefit is the test really giving you?
Most often you would want to do this because you're actually considering those privates a unit unto themselves (this sound like you, since you say you are testing those private methods directly already!). If that's the case, it's best to extract that logic into its own class, test it, and then in the remaining code interact with a mock/stub version of that new unit. If you do that, your code has a better structure and you don't need to fall back on the voodoo magic that is PowerMock. A fantastic reference to do these kinds of refactorings is Michael Feathers' Working Effectively with Legacy Code.
You may check java instrumentation to do so
As one of solution can be used proxy from inner classes. You need add inner class inside every your class which must be tested.
But it is not very good solution for big product project. its require create addition script for remove generated classes from your release files(jar/war).
But more easier way will be used PowerMock as wrote in comments bellow(or upper :)) - http://code.google.com/p/powermock/wiki/MockPrivate
Would it be possible to provide the class in question with another object, to which the private methods are moved and made public? In that case, it would be easy to create a test dummy for that interface.
If calling the right "private method" has no observable outside result, are you sure you want to test this? Maybe shouldn't.
If the end result is the same regardless of whether the private method gets called, and you still want to observe its invocation, you could make the method public and move it to its own class, and mock that class. Then you could verify (using Mockito or a similar framework) whether your method is being called.
Code coverage tools do this kind of thing by re-writing the bytecode before the tests are actually run. So, it's got to be possible, but it's non-trivial.
Update: writing a unit test that requires that the "right" private method be called kind of makes the job of refactoring a real pain because then you have to re-write all your tests. That kind of defeats the purpose of the tests.
I have a method that I want to be called each time one of the other methods is called. I dont want to have to explicitely call it each time. Is there a way to have the other methods naturally call that method before executing its own code?
If I have a method thats called isThere() and I want it called in each other method, I dont want to have isThere() written in each method. I was hoping there would an easier way to do this.
You should look into AOP - Aspect Oriented Programming.
Since you are using Java, I recommend you to take a look at AspectJ.
You could access all other methods through another method, which first calls there, and then uses a parameter you passed to it to identify which method you want it to use, using a switch statement or something similar.
You may take a look into Observer pattern, which may also solve your problem a bit differently. Read the Wikipedia page linked here. Alternatively, you can read the Observer pattern from the Head First Design Pattern book.