How to Tell a Mockito Mock Object to Return Something Different the Next Time It Is Called

Mockito return value only when method is called for second time

In your unit test you can simply add the then clause twice. Like this -

@Test
public void yourUnitTest(){
when(nameManager.getName(anyString())
.thenReturn(null)
.thenReturn(someValue);
// your test
}

This will only return value when called second time and it will return null first time around.

Mockito Mock object being ignored and actual function being called

I was able to figure out what the problem was by running the test in debug mode.

I found that the @PostConstruct function in my Class B was getting called before my test function. So class B was creating its own beanClient object different from the mock in my test class. That's why it was going into the function and not mocking it.

I was able to resolve it by changing Class B like so:-

@Service
public class B{

@Autowired
private C client;

public JSONObject getAns(String request){
// This is the line that I intend to mock but gets ignored. It goes into the function search instead.

JSONObject resp =client.search(searchRequest,requestHeaderOptions); // assume that these two variables passed as arguments are not null and have some content.

// searchRequest is of type SearchRequest
// requestHeaderOptions is of type RequestOptions
return resp;
}

I had to change it into a non-static function.

Have Mockito Return Varying Number of Different Values for Invocations

Mockito offers the AdditionalAnswers
class for doing something along those lines, to quote the javadocs:

Additional answers provides factory methods for answers

This allows for more dynamic configuration of Mock response behaviour.
As this answer to a similar question suggests, AdditionalAnswers.returnsElementsOf​(Collection<?> elements) could be used to supply the mock with a List of answers that will be used in order.
Caveat from the documentation should be noted there, it will automatically re-use the last element for all calls after iterating to the end, so if you want to simulate not returning answers after a certain point this will not work.

If I understand the documentation correctly, you could also customize the behaviour even further by utilizing the delegatesTo() method to relay the call to a (possibly stateful) object of your choice, or utilize the answer() methods accepting functional interfaces for supplying a function that responds in a stateful manner.

Is it possible to return a mock object for a method call based on a local variable in the actual class?

You could use two account objects and specify the accountID instead of anyString()

AccountObject goodAccount = new AccountObject();
AccountObject badAccount = new AccountObject();

goodAccount.setGoodAccount(true);
badAccount.setGoodAccount(false);

when(soapService.getAccountObject("abc123")).thenReturn(goodAccount);
when(soapService.getAccountObject("def456")).thenReturn(badAccount);


Related Topics



Leave a reply



Submit