简体   繁体   English

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

[英]How to deal with side effects of mocked method with JUnit/Mockito

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. SomeService内部,参数图填充了一些值,例如本示例中的“名称”。 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(); 当我执行此测试时,在此行上得到一个NullPointerException: 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. ,这是有道理的,因为应该填充此地图的方法是模拟的,而parameters.get("name")为null。 Let's also assume that I really want to have a String returned from doLogic(parameters) , so it cannot be the parameters map. 我们还假设我真的想从doLogic(parameters)返回一个String,因此它不能是参数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 ;-) ) (这里的代码示例是为即时编写的,因此,如果在编写它们时没有发现任何愚蠢的错误,请原谅我;-))

Can be done using the controversial thenAnswer method. 可以使用有争议的thenAnswer方法来完成。

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

But JB's comment is correct. 但是JB的评论是正确的。 This is not a great idea. 这不是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM