Java 如何用JUnit/Mockito处理mock方法的副作用

Java 如何用JUnit/Mockito处理mock方法的副作用,java,spring-boot,junit,mockito,Java,Spring Boot,Junit,Mockito,这可能是一个愚蠢的问题或是一些显而易见的问题,但无论如何,我真的在努力解决这个问题。 假设我们在测试的方法中有以下逻辑: @Service public class ServiceToTest() { @Autowired private SomeService someService; public String testMethod() { Map<String, String> parameters = new HashMap<

这可能是一个愚蠢的问题或是一些显而易见的问题,但无论如何,我真的在努力解决这个问题。 假设我们在测试的方法中有以下逻辑:

@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;
    }
}
当我执行此测试时,我在这一行上得到一个NullPointerException:
String name=parameters.get(“name”).toLowerCase()
,这很有意义,因为应该填充此映射的方法是模拟的,
参数.get(“name”)
为空。我们还假设我确实希望从
doLogic(parameters)
返回一个字符串,因此它不能是参数映射

是否有方法指示模拟对象填充参数映射,或模拟映射对象本身?

(这里的代码示例是为这篇文章即时编写的,因此如果在编写过程中我没有注意到任何愚蠢的错误,请原谅我;-)

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


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

有办法。但这是代码应该重构的标志。为什么不从doLogic()返回一个包含结果字符串的对象和一个映射呢?是的,这是一个选项,但恕我直言,这似乎有点违反直觉。创建另一个对象来存储我想从我的方法返回的对象和我只想充实的映射。。。我想重构的最佳方法是在某个服务中创建一个专用的公共方法,以丰富/填充映射并返回它。这样我就可以很容易地模仿我想要回到地图上的东西。我只是这样做了,效果很好:)谢谢JB为我指明了重构的方向!
@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");
    }
}