【问题标题】:How to deal with side effects of mocked method with JUnit/Mockito如何使用 JUnit/Mockito 处理模拟方法的副作用
【发布时间】:2018-01-23 16:15:03
【问题描述】:

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

@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 内部,参数映射填充了一些值,例如本例中的“名称”。我想在我的单元测试中模拟这个服务。

考虑以下单元测试sn-p:

@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) 返回一个字符串,所以它不能是参数映射。

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

【问题讨论】:

  • 有办法的。但这表明代码应该被重构。为什么不从 doLogic() 返回一个包含结果字符串的对象和一个 Map?
  • 是的,这是一个选项,但恕我直言,这对我来说似乎有点违反直觉。创建另一个对象来存储我想从我的方法返回的对象和我只想丰富的 Map... 我想重构的最佳方法是在 SomeService 中创建一个专用的公共方法来丰富/填充地图并返回它。这样我就可以轻松地模拟我想要在地图中返回的内容。我刚做了这个,效果很好:)
  • 感谢 JB 为我指明重构的方向!

标签: java spring-boot junit mockito


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2022-01-04
    • 2011-10-17
    • 2020-03-20
    相关资源
    最近更新 更多