I have a method that looks that looks something like:
public Response methodA(ParamObject po, Supplier<Response> supplier)
the Supplier
contains a call to a method on another class.
I am attempting to wrap some code in the Supplier
in a more complex set of logic, something akin to a Strategy pattern, it does make the code easier to follow.
It looks something like:
public Controller {
private Helper helper;
private Delegate delegate;
public void doSomething() {
ParamObject po = ....
delegate.methodA(po, () -> {
helper.doSomethingElse(v1, v2);
}
}
}
In my test for Controller
I have mocked both Helper
and Delegate
, I wish to validate that helper.doSomething
is called with the correct parameter values, and then return a mocked response.
Given that delegate
is a mock, the Supplier
is never actually executed, so no verification of the calls to helper
can be mocked or verified.
Is it possible to do this? It feels like I should be able to tell mockito to capture the lambda, and or the variables the lambda itself captured and assert they are the right values return my mock response if they are the values I was looking for.
We can use Mockito class mock() method to create a mock object of a given class or interface. This is the simplest way to mock an object. We are using JUnit 5 to write test cases in conjunction with Mockito to mock objects.
Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().
If you need to mock a global variable for all of your tests, you can use the setupFiles in your Jest config and point it to a file that mocks the necessary variables. This way, you will have the global variable mocked globally for all test suites.
With Mockito, you create a mock, tell Mockito what to do when specific methods are called on it, and then use the mock instance in your test instead of the real thing. After the test, you can query the mock to see what specific methods were called or check the side effects in the form of changed state.
Assuming that your class Helper looks like this:
public class Helper {
public Response doSomethingElse(String v1, String v2) {
// rest of the method here
}
}
Then it could be done like this:
Helper helper = mock(Helper.class);
// a and b are the expected parameters
when(helper.doSomethingElse("a", "b")).thenReturn(new Response());
// a and c are not the expected parameters
when(helper.doSomethingElse("a", "c")).thenThrow(new AssertionError());
Delegate delegate = mock(Delegate.class);
// Whatever the parameters provided, simply execute the supplier to
// get the response to provide and to get an AssertionError if the
// parameters are not the expected ones
when(delegate.methodA(any(), any())).then(
new Answer<Response>() {
@Override
public Response answer(final InvocationOnMock invocationOnMock) throws Throwable {
return ((Supplier<Response>) invocationOnMock.getArguments()[1]).get();
}
}
);
Controller controller = new Controller();
controller.helper = helper;
controller.delegate = delegate;
controller.doSomething();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With