如何使用JUnit / Mockito处理模拟方法的副作用

时间:2018-01-23 16:15:03

标签: java spring-boot junit mockito

这可能是一个愚蠢的问题或明显的问题,但不过,我真的很难解决这个问题。 假设我们在被测方法中有以下逻辑:

@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;
    }
}

SomeService内,参数图中填充了一些值,例如本例中的“name”。我想在单元测试中模拟这项服务。

考虑以下单元测试片段:

@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");
    }
}

当我执行此测试时,我在此行上获得NullPointerException: String name = parameters.get("name").toLowerCase();,这是有意义的,因为应该填充此地图的方法被模拟,parameters.get("name")为空。我们还假设我真的想要从doLogic(parameters)返回一个String,所以它不能是参数map。

有没有办法以某种方式指示模拟对象填充参数图,或模拟地图对象本身?
(这里的代码示例是为这篇文章写的,所以请原谅我,如果有任何愚蠢的错误,我在编写时没有注意到;-))

1 个答案:

答案 0 :(得分:0)

可以使用有争议的thenAnswer方法完成。

https://static.javadoc.io/org.mockito/mockito-core/2.13.0/org/mockito/stubbing/OngoingStubbing.html#thenAnswer-org.mockito.stubbing.Answer-

但JB的评论是正确的。这不是一个好主意。