Layout of the same method with different parameters

I use mockito to test my business service, and it uses the utility that I want to make fun of. in each method of the service there are at least 2-3 calls for the utility with different arguments.

Is there a recommended way to use multiple when(...).thenReturn(...) for the same method but different arguments?

I also want to use any() marcher, as well as internally. Is it possible?

Update: sample code.

 @Test public void myTest() { when(service.foo(any(), new ARequest(1, "A"))).thenReturn(new AResponse(1, "passed")); when(service.foo(any(), new ARequest(2, "2A"))).thenReturn(new AResponse(2, "passed")); when(service.foo(any(), new BRequest(1, "B"))).thenReturn(new BResponse(112, "passed")); c.execute(); } public class ClassUnderTest { Service service = new Service(); public void execute() { AResponse ar = (AResponse) service.foo("A1", new ARequest(1, "A")); AResponse ar2 = (AResponse) service.foo("A2", new ARequest(2, "2A")); BResponse br = (BResponse) service.foo("B1", new BRequest(1, "B")); } } public class Service { public Object foo(String firstArgument, Object obj) { return null; //return something } } 
+6
source share
3 answers

One way could be to avoid too restrictive arguments to provide the expected results with just one thenReturn call.

For example, let's say that I want to mock this method:

 public String foo(String firstArgument, Object obj) { return "Something"; } 

Then you can mock him by providing as many results as you want:

 // Mock the call of foo of any String to provide 3 results when(mock.foo(anyString(), anyObject())).thenReturn("val1", "val2", "val3"); 

Calling foo with any parameters will give " val1 ", " val2 ", respectively, then any subsequent calls will contain " val3 ".


In case you care about the passed values, but do not want to depend on the sequence of calls, you can use thenAnswer to provide an answer that matches the second argument, as it is currently, but with 3 different thenReturn .

 when(mock.foo(anyString(), anyObject())).thenAnswer( invocation -> { Object argument = invocation.getArguments()[1]; if (argument.equals(new ARequest(1, "A"))) { return new AResponse(1, "passed"); } else if (argument.equals(new ARequest(2, "2A"))) { return new AResponse(2, "passed"); } else if (argument.equals(new BRequest(1, "B"))) { return new BResponse(112, "passed"); } throw new InvalidUseOfMatchersException( String.format("Argument %s does not match", argument) ); } ); 
+11
source

The correct way would be to match the arguments with eq() , but if you don't want to do this, you can just write a few return values.

 when(someService.doSomething(any(SomeParam.class))).thenReturn( firstReturnValue, secondReturnValue, thirdReturnValue ); 

Now the first call will return firstValue , the second secondValue and all subsequent thirdValue .

+1
source

I think: the β€œrecommended” way is the one that WORKS for you; and this is due to the least coding effort.

You must provide the THOSE specifications necessary for your test to do what it should do. There is no way around this.

If you really like the arguments you use, you must specify them accordingly. If you do not care; use any() .

0
source

Source: https://habr.com/ru/post/1014257/


All Articles