Reputation: 23
This might be a dumb question or something obvious to figure out, but nevertheless, I'm really struggling to solve this. Let's say we have the following logic within a method under test:
@Service
public class ServiceToTest() {
@Autowired
private SomeService someService;
public String testMethod() {
Map<String, String> parameters = new HashMap<String, String>();
// eventParameters will be populated inside someService
String result = someService.doLogic(parameters);
// do something with the result here that doesn't really matter for this example
String name = parameters.get("name").toLowerCase();
return name;
}
}
Inside SomeService
the parameters map is populated with some values, like the "name" in this example. I would like to mock this service in my unit test.
Consider the following unit test snippet:
@RunWith(SpringRunner.class)
public class ServiceToTestTest {
@TestConfiguration
static class ServiceToTestConfiguration {
@Bean
public ServiceToTest serviceToTest() {
return new ServiceToTest();
}
@Autowired
private ServiceToTest serviceToTest;
@MockBean
private SomeService someService;
@Test
public void testShouldReturnJimmy() {
given(someService.doLogic(Mockito.anyMap())).willReturn("whatever");
String name = serviceToTest.testMethod();
assertThat(name).isEqualTo("jimmy");
}
}
When I execute this test I get a NullPointerException on this line:
String name = parameters.get("name").toLowerCase();
, which makes sense as the method that should populate this map is mocked and parameters.get("name")
is null. Let's also assume that I really want to have a String returned from doLogic(parameters)
, so it cannot be the parameters map.
Is there a way to somehow instruct the mock object to populate the parameters map, or to mock the map object itself?
(The code examples here were written for this post on the fly, so please forgive me if there are any stupid mistakes that I haven't noticed while writing them ;-) )
Upvotes: 2
Views: 2410
Reputation: 462
Can be done using the controversial thenAnswer method.
But JB's comment is correct. This is not a great idea.
Upvotes: 1