Mockito模拟一个方法,但使用其参数进行模拟返回

时间:2016-06-22 06:38:08

标签: java unit-testing mockito spy

有一种方法public Content createChild(String path, String contentType, Map<String,Object> properties)我想嘲笑。

我想以这种方式模拟使用任何类型的参数调用该方法,因此when()不起作用,因为我必须告诉它该方法应该接收哪些参数才能实际模拟。

所以我想实际上对任何方法调用做出反应,独立于其给定的参数(使用间谍?)然后调用某种“回调”来返回一个Content对象,我希望将它构建在一起给出方法的论据。

我在Mockito中找不到支持此功能的特定API。

4 个答案:

答案 0 :(得分:6)

您可以使用Matchers

您可以尝试以下内容:

when(service.createChild(anyString(), anyString(), anyMap()))
     .thenReturn(any(Content.class));

答案 1 :(得分:1)

您可以使用匹配器

MyClass m = mock(MyClass.class);
when(m.createChild(any(String.class), any(String.class), any(Map.class))).thenReturn(new Content());

您还应该能够以这种方式使用参数

when(m.createChild(any(String.class), any(String.class), any(Map.class))).thenAnswer(
       new Answer<Content>()
       {
           @Override
           public Content answer(final InvocationOnMock invocation) throws Throwable
           {
               return new Content((String) invocation.getArguments()[0], 
(String) invocation.getArguments()[1],
(Map) invocation.getArguments()[2]);
               }
           }
       }
       );

答案 2 :(得分:1)

当然可以。我为此编写了简单的单元测试

public class MockitoTest {


    private SampleService sampleService;

    @Before
    public void setUp() throws Exception {
        sampleService = Mockito.mock(SampleService.class);
    }

    @Test
    public void mockitoTest() throws Exception {
        when(sampleService.createChild(anyString(), anyString(), anyMapOf(String.class, Object.class)))
            .thenAnswer(invocationOnMock -> {
                //Here you can build result based on params
                String pathArg = (String) invocationOnMock.getArguments()[0];
                if (pathArg.equals("p1")) {
                    return new Content("Content for p1");
                } else if (pathArg.equals("p2")) {
                    return new Content("Content for p2");
                } else {
                    return invocationOnMock.callRealMethod();
                }
            });

        Content content = sampleService.createChild("p1", "any", new HashMap<>());
        assertEquals("Content for p1", content.getData());

        content = sampleService.createChild("p2", "any", new HashMap<>());
        assertEquals("Content for p2", content.getData());

        content = sampleService.createChild("whatever", "any", new HashMap<>());
        assertEquals("original", content.getData());

    }

    /**
     * Sample service with method
     */
    private static class SampleService {

        public Content createChild(String path, String contentType, Map<String, Object> properties) {
            return new Content("original");
        }

    }

    /**
     * Content example
     */
    private static class Content {

        private String data;

        Content(String data) {
            this.data = data;
        }

        String getData() {
            return data;
        }
    }

}

答案 3 :(得分:0)

您可以根据需要尝试使用 eq() any()

when(service.createChild(eq("helloe/hi"), any(String.class), any(Map.class)))
     .thenReturn(any(Content.class));

eq -如果要为参数使用特定值,则可以使用eq()方法。

任何-有时我们想模拟给定类型的任何参数的行为