'How to mock a method with varargs and a thenAnswer lambda?

I'm trying to mock a method that has a vararg in its signature. The original method:

public class ThisThing {
  public String doIt( Sumpin a, String b, String... c) {
    // return a string
  }
}

Here's my attempted mock (I read that any() matches a vararg):

when(mockThing.doIt(
    any(),
    any(),
    any()
  ))
.thenAnswer( (a, b, c) -> b );

But Eclipse is flagging thenAnswer as erroneous:

The method thenAnswer(Answer<?>) in the type OngoingStubbing<String> is not applicable for the arguments ((<no type> a, <no type> b, <no type> c) -> {})

But also the lambda expression as erroneous:

Lambda expression's signature does not match the signature of the functional interface method answer(InvocationOnMock)

I've also tried changing the second any() matcher to anyString() to no effect. Oddly, the errors all disappear if I replace the lambda with a -> a. Are multiple arguments not allowed in the lambda?

What am I doing wrong and can I do what I'm trying to do?



Solution 1:[1]

I am not sure what you problem is. You can mock a specific amount of method parameters and the mock will work

TestClass

@Mock
private SomeService someService;

@Test
void someTestMethodTest() {
  when(someService.testSomething(any(),any(),any(),any())).thenAnswer(new Answer<Object>() {
    @Override
    public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
        return "ooooo";
    }
  });
  String testsomething = someService.testsomething("a", "a", "a", "a");
  System.out.println(testsomething);
}

"actual implementation" in someService

public String testSomething(String a, String b , String... c){
  return "asad";
}

Are you sure that you want to work with "thenAnswer" and not with "thenReturn ? Working with return is usually easier.

EDIT:

When explicitly working with lambda is required the alternative would be

when(someService.testsomething(any(),any(),any(),any())).thenAnswer(a -> "oooo");

When explicitly getting inputparameter "2" as return the

when(someService.testsomething(any(),any(),any(),any())).thenAnswer(a -> a.getArguments()[1]);

will do the trick.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1