Reputation: 115
I'm trying to mock a request using a List of String and create an List of objects using parameter passed... something like:
when(tagDao.findByNameInOrderByName(Matchers.anyListOf(String.class))).thenReturn(new ArrayList<Tag>() {
/**
*
*/
private static final long serialVersionUID = 8227782193263533677L;
{
add(new Tag("name"));
add(new Tag("surname"));
}
});
I've tried something like
when(tagDao.findByNameInOrderByName(Matchers.anyListOf(String.class))).thenReturn(new Answer<List<Tag>>() {
@Override
public List<Tag> answer(InvocationOnMock invocation) throws Throwable {
// Object[] args = invocation.getArguments();
List<Tag> tags = new ArrayList<Tag>();
return tags;
}
});
And I got the following error: the method thenReturn(List) in the type OngoingStubbing> is not applicable for the arguments( new Answer>() {})
Upvotes: 0
Views: 1779
Reputation: 140553
I think you looking you looking for a technical solution ... to a problem that should be solved in a different way.
What you have: some method is invoked by your code under test, passing a List of values. And now you want to somehow return a result build "around" those incoming values. The other answer tells you how to get there (where I would have looked to see if you can do that using an ArgumentCaptor).
But let's step back. Keep in mind that you write unit tests to test one specific aspect of the public contract of some method. But it seems that there will be different invocations of findByNameInOrderByName()
. And now you are looking for a way to generate different return results for different input.
My suggestion is not not do this. Instead: clearly separate things into different testcases. Like in:
@Test
public void testXyzWithFooBar() {
when(tagDao.findByNameInOrderByName(Arrays.asList("foo", "bar").thenReturn(Arrays.asList(x, y));
... call xyz ...
@Test
public void testXyzWithFooOnly() {
when(tagDao.findByNameInOrderByName(Arrays.asList("foo").thenReturn(Arrays.asList(z, b));
... call xyz ...
In other words: I would rather strive to avoid the additional complexity of having a mock object return something implicitly based on input parameters.
Instead: clearly express the expected cases explicitly. This also leads to stricter tests. Your idea means: anything can go to that mocked method call. My version clearly states what you expect to happen.
Upvotes: 1
Reputation: 823
I think you should use thenAnswer
instead of thenReturn
when(tagDao.findByNameInOrderByName(Matchers.anyListOf(String.class))).thenAnswer(new Answer<List<Tag>>() {
@Override
public List<Tag> answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments();
List<Tag> tags = new ArrayList<Tag>();
return tags;
}
});
Upvotes: 3