In Mockito when we try to mock a method call, let's say we configure something like this
when(exampleClass.getOutputString(anyString())).thenReturn("output1");
This is all understandable. But my question is what is the reason this thenReturn("output1") method returns an OngoingStrubbing object (same as what when(exampleClass.getOutputString(anyString())) method returns), so that we can do something like this
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenReturn("output2");
or
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenThrow(new IllegalArgumentException());
However, both the above cases, when using the mock, it only returns "output1" and that's all the story. Anyone knows, why this chaining feature is present, and what are the uses of it? Kind of same thing applies to doReturn() too.
This means for the first call gives ouput1 and in the second call gives output2, and so on.
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenReturn("output2");
, The second one you need to reach one condition in the target test class so gives
output1 for the first case but in the second one you want to fail to test for example
try-catch clause or see if the code cover the broken scenarios like exceptions
when(exampleClass.getOutputString(anyString())).thenReturn("output1").thenThrow(new IllegalArgumentException());
Related
Imagine you have method someMethod, how would you go by to test it?
Mockito.when(someClass.someMethod(someParam)).thenReturn(someValue);
var bar = foo() // SUT: ends upp calling someMethod somewhere in the stack
assertThat(bar).isEqualTo(someValue);
vs
Mockito.when(someClass.someMethod(someParam)).thenReturn(someValue);
var bar = foo() // SUT: ends upp calling someMethod somewhere in the stack
verify(someClass, times(1)).someMethod(someParam)
assertThat(bar).isEqualTo(someValue);
It is true that the Mockito.when is "kind of" verifying that someClass.someMethod is being called with the correct arguments. Personally I like the idea of having clear assertions/verifications so that the tests can serve as a form of documentation. I don't like giving my mocks double-responsibilities, I want to keep my mocks just simply as "mocks".
So back to my question.
What is the preferred way, using Mockito.when combined with Mockito.verify or only Mockito.when?
When defines the behaviour of the Mock - declaratively defining the way the mock will respond when methods are invoked with different parameters.
Verify is used to check whether the Mock has been interacted with in various ways.
Here are some URLS to the official Mockito documentation, which I hope will help.
Stubbing - with when
Argument matchers
Verification in order
Making sure interaction(s) never happened
on mock
It's probably worth performing a search for some other examples.
I think this question has been answered in https://stackoverflow.com/a/35301264/473064.
The summary is:
In short, it is considered good Mockito style to explicitly verify only the interactions that can't be implied from well-crafted stubs and postcondition assertions. They may be good calls for otherwise-unmeasurable side effects—logging code, thread executors, ArgumentCaptors, multiple method calls, callback functions—but generally should not be applied to stubbed interactions.
One point that I would add is that sometimes if we want to do a verifyZeroInterations to ensure that no unexpected calls occurred, we would have to first exhaust the known calls by verifying them.
What I usually do is to perform the simplest verify(mock, times(n)).someMethod(anyClass()) as generally as possible without repeating the more specific argument matching that I have already specified in the stubbing, which reduces the duplication as much as possible.
Example:
when(someObject.someMethod(eq("abc"))).thenReturn(someValue);
when(someObject.someMethod(eq("def"))).thenReturn(otherValue);
when(someObject.someMethod(endsWith("suffix"))).thenReturn(anotherValue);
var bar = foo();
assertEquals(expectedBar, bar);
verify(someObject, times(3)).someMethod(anyString());
verifyZeroInteractions(someObject);
Regarding your concern in the comment:
The problem I see is, if a new developer reads the test, they won't know the subbed method is part of the verification process.
The stubbed method is not part of the verification process. It's part of the test case setup, i.e., the Given step.
I think your example might be a little bit misleading. The final output from foo() is usually a transformation of the response from someMethod, i.e., someValue in the example. So if the stubbed method is not called and returned with the correct value, the test would have failed anyway. The said developer would then have to look at the mocking and understand how the test case works.
In the updated example below, there is no need to verify that someMethod is called because if it didn't get called, the assertion would fail.
Mockito.when(someClass.someMethod(someParam)).thenReturn(someValue);
var bar = foo() // SUT: ends upp calling someMethod somewhere in the stack
var expectedValue = // a value depending on `someValue`
assertThat(bar).isEqualTo(expectedValue);
I'm testing a method that call same method (db.getData()) twice. But I must return two different values.
Mockito.when(db.someMethod()).thenReturn(valueOne).thenReturn(valueTwo);
Then I tried out multiple thenReturn().
Unfortunately I'm getting only valueTwo for first & second db.getData() method call.
You are not showing a lot of context but here are some ideas:
make sure db is really a mock object
use the debugger to check if db.someMethod() is called twice as you expect
You can also use thenReturn(valueOne, valueTwo); although that should not make a difference
I suspect that your method is called more than twice and that you are missing the first invocation (which returns valueOne) and only looking at subsequent invocations (which will all return valueTwo).
See the API:
//you can set different behavior for consecutive method calls.
//Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls.
when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");
It's probably you are debugging and when you want to fetch the data of the breakPoint line, you are fetching from mock, so it will return one of it's thenReturn() parameters, so when you resume the test, it will test it with the second parameter.
I recommend you if you doubt it's working properly, one time fetch all thenReturn() items and after that you agree they're OK, start the test again with no tracing thenReturn() items.
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 want to check preconditions on a base class so that I know subtypes will always use constructor arguments that are valid.
Let's take as an example a constructor that:
takes 2 or more parameters
takes parameters of different types
for one parameter, it performs multiple checks (e.g. String is not null and not empty)
How would one best use the Guava preconditions approach in that case?
In a mock example like this: (this is contrived!)
protected AbstractException(String errorMessage, Throwable errorCause) {
super(errorMessage, errorCause);
checkNotNull(errorMessage,
ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK, "errorMessage");
checkArgument(!errorMessage.isEmpty(),
ErrorMessage.MethodArgument.CANNOT_BE_EMPTY_STRING_CHECK,
"errorMessage");
checkNotNull(errorCause, ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,
"errorCause");
}
I end up calling super before checking the arguments because a call to super needs to be the first line of the method and, although I could do super(checkNoNull(errorMessage)), I cannot do the same wrapping using checkArgument because that returns void. So the dilemma is:
Where do I put the checks on all arguments? I don't want to create a Builder just for that
How do I "group" checks as in a fictitious checkStringNotNullAndNotEmpty()
Should I rather think about integration with matchers frameworks? (hamcrest, fest assertions...)
I use the odd-looking ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK because the default throw does not include an error message so from the testing side I cannot recognise this as an argument validation failure rather than a "any" NPE?
Am I doing it all wrong?
This should have been a comment, but it's too long.
Calling super before the test is harmless provided that the super ctor doesn't do things which it shouldn't do anyway.
It could be prevented via a static builder method, you need no Builder. But it's not worth it.
I doubt that grouping tests is generally useful; if it was, then there would be a such method already. But if you need one such a concrete thing more than twice, then write your own; if it comes often, report it to the Guava team as an RFE.
I'm pretty sure, matchers are an overkill here as you're just creating an exception, i.e., something used only rarely (I hope). As your test is runtime only, it can't really help to catch errors. It would be nice, if you could statically ensure a "properly" constructed exception, but it's impossible in pure java.
More important: The exceptions you're throwing are probably inferior to the ones you'd get without all the checks. Imagine the user provides a cause and no message. That's bad, you think, but you replace it with an NPE lacking any cause. That's worse.
Look at Guava's Preconditions.format (package private). They could check the correct number of arguments first, but they do not. You can provide too few or too many, which is an error, but ignoring it is the best way to handle it.
Mockito seems like a pretty sweet stubbing/mocking framework for Java. The only problem is I can't find any concrete documentation on the best ways of using their API. Common methods used in tests include:
doXXX(???) : Stubber
when(T) : OngoingStubbing
then(T) : OngoingStubbing
verify(???) : T
given(T) : BDDOngoingStubbing
willXXX(???) : BDDStubber
When you see examples of Mockito in practice, you see code like:
when(yourMethod()).thenReturn(5);
From all the docs I've read, I've identified several "patterns" of Mockito "grammars" obtained from daisy-chaining these method calls together like the example above. Some common patterns I've found are:
When/Then: when(yourMethod()).thenReturn(5);
Given/Will: given(yourMethod()).willThrow(OutOfMemoryException.class);
Do/When: doReturn(7).when(yourMock.fizzBuzz());
Will/Given/Do: willReturn(any()).given(yourMethod()).doNothing();
Verify/Do: verify(yourMethod()).doThrow(SomeException.class);
What I'm choking on is how to select the right pattern/combination of method calls to model my test cases. It seems like you can daisy-chain these together in seemingly endless combos and I'm not sure what pattern is right for which problem.
Can some Mockito Guru help shed some light as to which patterns/combinations of Mockito methods are used for which types of test cases (and why)? Thanks in advance!
There are several disadvantages to the when/thenReturn, when/thenThrow and when/then syntaxes. For example,
In the case of when/thenReturn, if the return type is a generic with a
wildcard, and you wish to return a mock of the same type, you will be unable
to avoid a compile warning.
You can't use when/thenThrow and when/then for a void method.
You can't use these syntaxes on Mockito spies.
You can only call when once for each combination of mock object,
method and arguments, unless you call reset on the mock.
Calling when multiple times for one combination of mock
object and method, when you are using argument matchers, can lead to problems.
I find these cases difficult to remember. So instead of trying to keep track of when the
when/thenReturn, when/thenThrow and when/then syntaxes will and won't work, I prefer to avoid them completely, in favour of the doReturn/when, doThrow/when and doAnswer/when alternatives. That is to say, since you'll occasionally need doReturn/when, doThrow/when and doAnswer/when, and you can ALWAYS use these methods, there is no point in learning how to use when/thenReturn, when/thenThrow and when/then.
Note that doReturn, doThrow and doAnswer can be chained together in the same way as thenReturn, thenThrow and then. What they don't have is an option for returning several values (or throwing several exceptions, or running several answers) within a single call to doReturn, doThrow and doAnswer. But I find that I need to do this so seldom, that it doesn't really matter.
There's one more disadvantage to doReturn, which I consider insignificant. You don't get compile time checking of the type of its argument, like you do with when/thenReturn. So if you get the argument type wrong, you won't find out until you run your test. Frankly, I don't care.
In summary then, I have been using Mockito for more than two years, and I consider the consistent use of doReturn, doThrow and doAnswer to be a Mockito best practice. Other Mockito users disagree.
Mockito often have several ways of doing things.
I find myself using mostly:
// Setup expectations
when(object.method()).thenReturn(value);
when(object.method()).thenThrow(exception);
doThrow(exception).when(object.voidMethod());
// verify things
verify(object, times(2)).method();
verify(object, times(1)).voidMethod();
I've found that i can do 95% of what i need to with these three kinds of calls.
Also, what version of Mockito are you using? "given" and "will" constructs are not present in the latest version (1.9.0+)
However, there are cases where I want the return value or exception to respond to the input. In this case, you can use the Answer interface to inspect the method arguments and return an appropriate value.
public class ReturnFirstArg<T> implements Answer<T> {
public T answer(InvocationOnMock invocation) {
return invocation.getArguments()[0];
}
}
when(object.method(7)).thenAnswer(new ReturnFirstArg<Integer>());
The things in fact looks much simpler than you thought
REF: http://static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html
Verify:
In order to use Mockito, you need to understand one basic philosophy of Mockito: Stubbing and Verification is separated. Therefore, the "Verify/Do" you mentioned is in fact doing the "Verification" job, while the other 4 "grammars" is for stubbing. Stubbing define how the mock object will react in different situation. Verification is to make sure what the mocks is invoked as expected, in previous invocation to system under test (SUT).
When/Then , Given/Will:
Then it come to the "When" and "Given" families. You can simply treat them as aliases of each other. "Given" family is added in Mockito 1.8.x as to make it looks more aligned to BDD practices.
DoXxx:
In normal case we mostly use when(xxx).then(...) (and given(...).will(...) ) . However there are some case that syntax is not working. The most obvious case is when return type of the stubbed method is void. In such case when(mockObj.voidMethod()).thenThrow(anException) is not going to compile. As a workaround, an alternative syntax of Do/When is created, so you can write the previous line as doThrow(anException).when(mockObj.voidMethod())