IsaacLevon
IsaacLevon

Reputation: 2570

Mockito: How to set thenReturn() dynamically?

I have a method which accepts a list of items. I'd like the mocked method to return a corresponding list of the same size (i.e. List<Results>)

More generally, is it possible to set the returned value dynamically, with respect to the given input?

The problem is that I have multiple tests for the same method. Test A is for an empty list and test B is for a list with multiple objects. Yet, I have only one @Before method.

Upvotes: 1

Views: 2124

Answers (2)

Ankireddy Polu
Ankireddy Polu

Reputation: 1866

Well, the right way to do this would be:

import org.mockito.AdditionalAnswers;
String[] logEntry = // Some initialization code
List<String> logEntryList = Arrays.asList(logEntry); 
when(tuple.getString(1)).thenAnswer(AdditionalAnswers.returnsElementsOf(logEntryList));

On each invocation, successive elements of logEntry array are returned. Thus, ith invocation of tuple.getString(1) returns ith element of logEntry array.

P.S: The example in documentation of returnsElementsOf (as of this writing) is not updated (it still uses ReturnsElementsOf example): http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/AdditionalAnswers.html#returnsElementsOf(java.util.Collection)it

EDIT: Javadoc is now updated: https://javadoc.io/static/org.mockito/mockito-core/3.1.0/org/mockito/AdditionalAnswers.html#returnsElementsOf-java.util.Collection-

Upvotes: 1

GhostCat
GhostCat

Reputation: 140427

You can use thenAnswer, probably in combination with an ArgumentCaptor to achieve that.

But the real answer is: consider not doing that.

Unit tests should be straight forward. When something fails, you quickly look at the unit test and you already know where to look in the production code to spot the root cause. Anything that adds complexity to your tests might make that harder.

In other words: instead of thinking up complex test code that gives dynamic results ... rather write multiple simple tests. You are in control of what goes int your test. So when you want tests that receive 2, 3, 5 arguments, and you need to return 2, 3, 5 elements for each case: then write 3 different tests.

Upvotes: 1

Related Questions