Java unit test check if method is invoked without executing it - java

I have to test a method which invokes two void methods. I just want to check if the two void methods are invoked or not, but the method must be stubbed.
How do I do it? I tried to implement it using Mockito doThrow method, but not success.
doThrow(new RuntimeException()).when(mockedClass).methodName();
Wanted but not invoked: error
How do I solve my problem?

You can verify only calls in mocked stuff, e.g.
Foo bar = Mockito.mock(Foo.class);
ClassToTest testInstance = new ClassToTest(bar);
testInstance.doStuff();
Mockito.verify(bar, times(1)).someMethod(); // will pass if someMethod of Foo class was called in scope of testInstance.doStuff()
I'm not really sure that you should check actual method calls by expecting an exception. Could you provide some code/a bit more details about the context?

You actually need to use verifyMethod on Mockito. Here is someone who had the same issue. The example shown mocks the object, injects it and then checks to see if it was called or not.
Mockito : how to verify method was called on an object created within a method?

Related

Mock - make a spy class method return a specific value

I'm running some unit tests on a methodA of a spied instance of a class (let's say instance is myClass), which uses a helper method (lets call it helper(long num, ObjectA obA, ObjectB obB)) to determine the boolean value of a flag
The parameters of this class are all mocked, the class is instantiated with a spy call, and the method itself is a protected method with 3 parameters. The method is called with every run of methodA. MethodA sets the values of the parameters for the helper method
My question is, is there a way to make, in this specific test, the helper method return true?
I've tried to, using the following:
when(myClass.shouldSetFlag(anyLong(), any(ObjectA.class), any(ObjectB.class))).thenReturn(true);
but every time I get a null pointer exception.
Would really appreciate some insight, thanks!
Since you've provided only one line of code and no stack trace, I assume the NullPointerException is thrown from the shouldSetFlag method.
When you mock the method using when(...) Mockito actually replaces the matchers with default values during the method call in this line (it's still Java code, the method is still called). If you act on ObjectA or ObjectB instances inside the method, the actual code encounters a null reference and the exception is thrown.
From the docs:
Matcher methods like anyObject(), eq() do not return matchers. Internally, they record a matcher on a stack and return a dummy value (usually null).
You can also observe that in the Mockito code, since it's open source.
To work around that use doReturn(...) (see the docs here) - the actual method will not be called while mocking, yet it still will be registered in Mockito.

Test lambda expressions called by dependencies

I am trying to test some code inside lambda expression which is a call back from another class.
class EmailSender {
private EmailBuilder emailBuilder;
public void send() {
String testEmail = emailBuilder.buildEmail("Test Email", bodyContentAppender());
//send testEmail
}
private Consumer<Email> bodyContentAppender() {
//how to test this through JUnit?
return email -> email.appendBody("Body Content");
}
}
interface EmailBuilder {
String buildEmail(String templateName, Consumer<Email> contentAppender);
}
The lambda expression in the method getBodyContent is called from EmailBuilder which is a mocked dependency in the JUnit test for EmailSender. Since I am mocking the behavior of EmailBuilder, the code inside getBodyContentis not called from tests. How to test such piece?
EDIT:
Capturing the lambda expression through Argument Captors is not a solution in this case as the behavior of EmailBuilder is mocked and the actual methods are not called. Secondly, email.appendBody does some transformations on an object which is passed by an external API and not straightforward to create.
What you are trying to do here is essentially to verify that a factory method did in fact really return the correct object. There is this related question, where the consensus is to not test the result of a factory method beyond verifying that it does indeed return an object of the correct type. The behavior of that object should be tested in the UnitTests for that type.
In an answer to this related question on unit testing lambdas Stuart Marks argues that
If the code in the lambda is complex enough that it warrants testing, maybe that code ought to be refactored out of the lambda, so that it can be tested using the usual techniques.
Now, the real question is: If this was not a lambda, but a concrete class MyBodyContentAppender that implements the functional interface Consumer<Email>, how would you unit test that? What kinds of test would you write for this class?
You would probably write tests to verify that, given an Email, invoking accept() does indeed invoke appendBody() with the appropriate parameters, perhaps that invoking it with a null argument throws a NullPointerException etc. You would possibly not verify that email.appendBody() works as expected, because that is covered by the tests for Email. You may have to mock Email for these tests if it is difficult to create.
Well, all of these tests can also be performed for the lambda. Your problem is that the factory and the type of the created object are both private, so from the perspective of your test, the only way to access that object is via the parameter passed to the (mocked) emailBuilder.buildEmail().
If you use Mockito for mocking the emailBuilder, you could capture the arguments to this method via ArgumentCaptors (see 15. Capturing arguments for further assertions (Since 1.8.0)), I'm sure other mocking libraries provide similar functionality.
Most mocking frameworks allow you to check arguments that are used when invoking methods on mocked object. Respectively, you can capture them.
So:
acquire the parameter passed
simply invoke the "code" that it represents, and check if that makes the expected updates to an Email object you provided.
It will be easier to test if you actually supply the body content as an argument, and make sure the method is public. If you intend to keep the method as private, then you should test the public method calling it.
public Consumer<Email> getBodyContent(String body) {
//how to test this through JUnit?
return email -> email.appendBody(body);
}
Then you can test it as
#Test
public void testGetBodyContent(){
.... //send different arguments and assert
....
}
So when you want to unit test your code you must ensure that it's doing one job at a time. You method is named as getBodyContent but seems like is supposed to do no more work than appending to email body. Hence, you could pull out this method to be public.
Now you could pass the body and get the content.
#Test
public void testGetBodyContent(){
consumer<Email> consumer = EmailSender.getBodyContent();
assertEquals("Email Content", consumer.accept(<mocked Email object>).getBody())
}

Spying on an object after cast using Mockito

I'm using Mockito to write some unit tests. I ran into the following scenario:
public interface A extends ABase { }
where ABase is an interface with concrete methods in it. I'm using Mockito.spy() on an instance of A, and I want to verify a method foo() declared in ABase is called in a piece of code I'm writing. Inside said code, A is cast to ABase and foo() is called. However, I get a build error (method not found) on the line where I try and verify foo() was called in my test method, like this:
A bar = spy(new A());
//... (function I'm testing is called, A is cast to ABase and foo() called)
verify(bar, times(1)).foo(); //problem line, foo not found
Any suggestions as to what to do? Thanks!
EDIT: there were some errors in my original question. My apologies, it should be fixed now.
Apart from the fact that ABase cannot be a class, because A is an interface and interfaces cannot extend classes:
You're passing A to verify. This shouldn't even compile. Try using bar instead. Mockito expects a mock or spy to be passed to verify so you can verify invocations on a particular argument.

EasyMock expectations with void methods

I'm using EasyMock to do some unit tests and I don't understand the usage of EasyMock.expectLastCall(). As you can see in my code below, I have an object with a method that returns void getting called in some other object's method. I would think that I have to make EasyMock expect that method call, but I tried commenting out the expectLastCall() invocation and it still works. Is it because I passed EasyMock.anyObject()) that it registered it as an expected call or is there something else going on?
MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);
obj.methodThatReturnsVoid(EasyMock.<String>anyObject());
// whether I comment this out or not, it works
EasyMock.expectLastCall();
EasyMock.replay(obj);
// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);
The API doc for EasyMock says this about expectLastCall():
Returns the expectation setter for the last expected invocation in the current thread. This method is used for expected invocations on void methods.
This method returns you the handle of expectation through IExpectationSetters; which gives you ability to validate(assert) that your void method was called or not and related behaviors e.g.
EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();
Detailed API of the IExpectationSetters is here.
In your example you are just getting the handle and not doing anything with it hence you don't see any impact of having or removing the statement. It's very same as you call some getter method or declare some variable and don't use it.
You only need EasyMock.expectLastCall(); when you need to further verify anything other than "That the method was called. (same as setting expectation)"
Say you want to verify how many times the method was called so you will add any of :
EasyMock.expectLastCall().once();
EasyMock.expectLastCall().atLeastOnce();
EasyMock.expectLastCall().anyTimes();
Or say you want to throw an exception
EasyMock.expectLastCall().andThrow()
If you don't care then EasyMock.expectLastCall(); is not required and does not make any difference, your statement "obj.methodThatReturnsVoid(EasyMock.<String>anyObject());" is enough for setting up expectation.
You are missing EasyMock.verify(..)
MyObject obj = EasyMock.createMock(MyObject.class);
MySomething something = EasyMock.createMock(MySomething.class);
EasyMock.expect(obj.methodThatReturnsSomething()).andReturn(something);
obj.methodThatReturnsVoid(EasyMock.<String>anyObject());
// whether I comment this out or not, it works
EasyMock.expectLastCall();
EasyMock.replay(obj);
// This method calls the obj.methodThatReturnsVoid()
someOtherObject.method(obj);
// verify that your method was called
EasyMock.verify(obj);

mockito mock verify

//Let's import Mockito statically so that the code looks clearer
import static org.mockito.Mockito.*;
//mock creation
List mockedList = mock(List.class);
//using mock object
mockedList.add("one");
mockedList.clear();
//verification
verify(mockedList).add("one");
verify(mockedList).clear();
I don't understand what is the point of this construct? How does it help? How is it different from just calling the functions?
The documentation is rather thin.
Thank you
You wish to test that some method Foo of class A calls some method Bar on an object of class B. In other words, you're testing class A. During your test, you make a mock of class B. Then you pass this mock object to class A somehow (depending on how class A actually works). When your test runs the Foo method of class A, you are expecting the Bar method to get called on your mock of class B. By calling verify for the Bar method, after the test of the Foo method, you can check that the Foo method is actually working correctly - that it calls Bar.
When you do mockedList.add("one"); its performing the operation on the mocked object as same time it remembers your operation. So when you do verify(mockedList).add("one");, it verifies the add was called on mockedList with argument one.
Hope you get the difference.
the verify method of mockito is verify the method invoke times,if the invoke time is 1,we can omit this parameter, see the source code of Mockito Line 1473
public static <T> T verify(T mock) {
return MOCKITO_CORE.verify(mock, times(1));
}
so you code
verify(mockedList).add("one");
//is the same as
verify(mockedList,times(1)).add("one");
is indeed to verify the add method's executed once
Indeed in your example it's obvious, but main idea of verifying methods calls appear during real code testing - imagine that some code performs method call like:
class A{
....
service.doSomething(<some arguments>)
....
}
In order to test it you'll pass mock service object, but sometimes you want to verify particular arguments values passed for that call (or number of calls), so you'll use verify like in your example.

Categories