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.
Related
Is there a way to use a service method (a method that is implemented in the service layer (Interface) ) only in test classes?
in my service interface i have a method that i want to use it only in test class
and prevent or show some warning to other developers that doesn't use it in their
managerImpl or other palace such as controller
Lets be precise about wording:
If you are really talking about a method of an Java interface; then Java8 would allow you to provide a default implementation that could throw an exception for example; and then you have very specific classes that implement this interface and maybe override that one method for test purposes.
If you are talking about "interfaces" in general; such as "the list of methods of some class" ... then this kind of "base throws" and "children override" could work as well.
Of course, the first answer might be visibility itself. If we are not talking about a real interface; you could at least make the method package protected; then usage is restricted to the same package.
Another option would be to follow ISP and segregate your interfaces. If there is something that should only be used for "testing"; then consider putting those things into some "TestSupportInterface"; or something alike.
But again; most of these ideas work "by convention"; by providing some sort of information that the user has to digest ... but that can't be enforced.
Finally: you could consider to change your production code. Very often you might not need such "special test getters". In other words: if your tests are working like "fetch state of X. do something with X. fetch state of X again and compare". Sometimes this can be changed to behavior based testing (you don't check what happens to X; but you check what X does to Y, Z, ...).
No, there's no concept in Java to warn developers about using methods.
Rethink if you 'really' need such a method, or if you could change your design to not require such a back door. (e.g. utilize the power of dependency injection). From my experience this is always possible.
If you are still convinced that you want this method implement it in your test code (e.g. by subclassing), not in production code.
It's generally better not to put anything in your production code "only for tests".
You could create a service dedicated to all users suppression and place it in your test classpath.
Depending on your implementation, this service might be a subclass of your production user service.
In addition to the other good answers: If you really need a method to be called by a test case but not by production code, you can make this method private. So unless someone changes the visibility nobody will use this method. And in your test case you can call it via PrivateAccessor.
But be careful: This is mostly considered as code smell. For your IDE this is a private and unused method, so there will be a warning message. And someone else could remove this method because of this.
One of unit test best practices is to make each test independent to all the others. Lets say I want to test add() method of a BoundedPriorityBlockingQueue custom class:
public void testAdd() {
BoundedPriorityBlockingQueue q = BoundedPriorityBlockingQueue();
q.add(1);
assertEquals(1, q.size());
}
as you can see currently testAdd uses size() method so it depends on it but I dont want testAdd() to fail when size() is broken. What is the best practice in this situation?
What is the best practice in this situation?
Just suck it up, bearing in mind that tests are meant to serve you, not the other way round.
Will your tests break if something goes horribly wrong? Yes.
Will it be clear where the problem is? Probably, given that anything using size will fail.
Is this test driving you towards a less testable design? No.
Is this the simplest approach to testing add, which is robust in the face of changing implementation details? Probably. (I'd test that you can get the value out again, mind you.)
Yes, it's sort of testing two parts of the same class - but I really don't think that's a problem. I see a lot of dogma around testing ("only ever test the public API, always use AAA" etc) - in my experience you should temper that dogmatism with a healthy dose of pragmatism.
The goal is to make all test methods independent of other test methods, and this method is independent. It will pass or fail based on the operation of the methods in the class under test, regardless of what you do in other test methods.
It's fine for this test to fail if another method from the class under test is broken. If size() is broken you'll have multiple test failures (this one and the one that explicitly tests size()) so it will be obvious where the problem is. If add() is broken, only this test will fail (along with any other methods that rely on add()).
As others have already said, if your size method is broken the test will fail anyway so you have a reason there to investigate and understand why is that happening.
Anyway, if you are still interested on having such independence between your tests you could go for a white-box testing strategy: I guess that your BoundedPropertyBlockingQueue uses internally either any of the java.util collections, an array or an collection implementation from other provider (Guava, Apache Collections, etc) that you rely on so you don't need to verify that those structures work as they are expected to do.
So, define that internal structure as protected, place your test class in a package with the same name and, instead of relying on the implementation of the size method, go into the guts of the BoundedPropertyBlockingQueue:
BoundedPriorityBlockingQueue q = BoundedPriorityBlockingQueue();
q.add(1);
assertEquals(1, q.contents.size()); // assuming that `contents` attribute is a collection.
The main drawback is that now if your internal implementation of the queue changes, you'll need to change the test whilst with your previous test method you won't need to.
IMO I would chose your current implementation, is less coupled and, at the end, meets its goal.
There's nothing wrong with doing such cross-testing - some methods tend to live in pairs (add/remove, enqueue/dequeue, etc) and it makes little sense to test one without its complementary part.
However, I would give a bit more thought to how the add method will be used by your clients (class users). Most likely won't call add only to determine whether size changed, but rather to later retrieve added item. Perhaps your test should look more like this:
BoundedPriorityBlockingQueue q = new BoundedPriorityBlockingQueue();
QueueItem toAdd = 1;
QueueItem added = q.dequeue();
assertEquals(toAdded, added);
On top of that you can also add guard assert to the test above (to assure queue doesn't start with some items already added) or even better - include separate test that guarantees initial state of queue (size is 0, dequeue returning null/throwing).
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 class A<X, Y> and I want to refactor it to A<Y, X> in a way that all the references to it would be modified as well.
I don't think that has been implemented in Eclipse yet. It's a rather rare refactoring, though...
But if your type hierarchy below A is not too complex yet, try using this regex-search-replace (where A|B|C means A and all subtypes of A, e.g. B and C):
\b(A|B|C)<\s*(\w+)\s*,\s*(\w+)\s*>
update: since you want to match more sophisticated stuff, try this (without the artifical line-breaks):
\b(A|B|C)<
\s*((?:\w+|\?)(?:\s+(?:extends|super)\s+(?:\w+|\?))?)\s*,
\s*((?:\w+|\?)(?:\s+(?:extends|super)\s+(?:\w+|\?))?)\s*>
replace by
$1<$3, $2>
Since you're using Eclipse, you can manually check every replacement for correctness
In Eclipse right-click on the method, then Refactor->Change method signature, you can change the order of the parameters there
If you aren't using Eclipse (or another tool that has good refactoring - highly recommended if you're aren't), then I can think of two ways to do this:
First:
If you're using TDD, then write a test that will only succeed when the variables are properly swapped. Then make the change to the method signature, and make sure your test passes.
Second:
1. Remove the 2nd parameter from the method signature, which will throw compilation errors on all calls to that method
2. Go to each of the lines that are failing compilation, and carefully swap the variables
3. Put the 2nd variable back into the method signature, in the new, reversed order
4. Run some tests to make sure it still works the way you expect it to
The second method is obviously ugly. But if you're aren't using an IDE with good refactoring support, compilation errors are a good way to capture 100% of the calls to that method (at least within your project). If you're writing a code library that is used by other people, or by other programs, then it becomes much more complicated to communicate that change to all affected parties.
Hii...
Is there any way to find out if the method call originated from a test class?
If its from a test class... then I need to initialize some dummy values for the variables in the class . I would like to write the Test Class with minimal change in the source code...
The class is following a singleton pattern..So its private constructor gets called which is calling some code which is blocking my testing. So I need to call my dummy methods from within in the private constructor so that it works smoothly..
Currently I am doing this...
StackTraceElement[] stack = new Throwable().getStackTrace();
boolean blnFrmTesting = false;
for (StackTraceElement stackTraceElement : stack) {
if(null != stackTraceElement && null != stackTraceElement.getFileName() && stackTraceElement.getFileName().endsWith("Test.java")) {
blnFrmTesting = true;
break;
}
}
return blnFrmTesting;
Is this a correct method...Or is there any other way.. like checking annotation...("#Test")
Well, for the technical part, I suggest you should instead try to see if class name contains Test, instaead of file name, which is (although Java specification tries to normalize it) always a little more fuzzy (think about inner class, as an example).
However, in a more general fashion, your code seems to ignore roughly ten years of Java engineering by ignoring the existence of test frameworks (JUniot, TestNG) and their associated ecosystem. Particularly, to define "dummy values", the domain of mocking frameworks is the way to go. There are currently quite a few interesting alternatives :
JMock
Mockito
EasyMock
JMockIt
Obviously, they may interfere with your singleton (or not). However, I must tell you that with the davent of IoC frameworks, the singleton pattern is now generally considered to be deprecated.
Irrespective of whether you find an answer to this question or not, it might make more sense not to perform this check in the first place, and structure your code accordingly... code which does something else when called by a test isn't really tested, is it?
You could also take a look at using a DI pattern and framework like Guice or Spring... that would make things a lot easier to test, while probably resulting in less and simpler code.
I generally agree with Sudhir, and do not really understand what did Riduidel want to say recommending to use Mocking. Mocking is fine if you wish to simulate the class' environment and neighborhood.
I think that your method is fine. You can really improve it if you add check of #Test annotation and a fact that the class extends TestCase. If you add support JUniot and testNG you can even publish your code and probably other people can use it.
But I think that probably you can even simplify the method. I used special system property for this purpose. Typically I had to identify that the code is running under application server, so I used property typical for application server. For example jboss.server.name for JBoss and catalina.base for Tomcat. If JUnit does not create any special property you can do it yourself in the beginning of test and check in code.