Solon

使用 Mock 测试

</> markdown

没有用过 mock 的同学,此文可以做个引子。具体知识还是要网上多多搜索。

1、基于 mockito 测试

mockito 是非常有名的 mock 框架。在 Solon Test 的三个适配插件里,已添加 mockito-core 依赖。可以直接使用:

public class MockTest {
    @Test
    public void testBehavior() {
        List<String> list = mock(List.class);
        list.add("1");
        list.add("2");

        System.out.println(list.get(0)); // 会得到null ,前面只是在记录行为而已,没有往list中添加数据

        assertFalse(verify(list).add("1")); // 正确,因为该行为被记住了

        assertThrows(Error.class, () -> {
            verify(list).add("3");//报错,因为前面没有记录这个行为
        });
    }

    @Test
    void testStub() {
        List<Integer> l = mock(ArrayList.class);

        when(l.get(0)).thenReturn(10);
        when(l.get(1)).thenReturn(20);
        when(l.get(2)).thenThrow(new RuntimeException("no such element"));

        assertEquals(l.get(0), 10);
        assertEquals(l.get(1), 20);
        assertNull(l.get(4));
        assertThrows(RuntimeException.class, () -> {
            int x = l.get(2);
        });
    }

    @Test
    void testVoidStub() {
        List<Integer> l = mock(ArrayList.class);
        doReturn(10).when(l).get(1);
        doThrow(new RuntimeException("you cant clear this List")).when(l).clear();

        assertEquals(l.get(1), 10);
        assertThrows(RuntimeException.class, () -> l.clear());
    }

    @Test
    void testMatchers() {
        List<Integer> l = mock(ArrayList.class);
        when(l.get(anyInt())).thenReturn(100);

        assertEquals(l.get(999), 100);
    }
}

2、基于 mock web server 测试

使用 web server 的 mock,需要引入第三方依赖包,比如 okhttp3 出品的:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>mockwebserver</artifactId>
    <version>${okhttp.version}</version>
    <scope>test</scope>
</dependency>

这个插件很有意思,它会启动一个 http server,模板输出指定的内容:

public class MockWebTest extends HttpTester {
    public final static String EXPECTED = "{\"status\": \"ok\"}";
    
    @Rule
    public MockWebServer server = new MockWebServer();

    @Test
    public void testSimple() throws IOException {
        server.enqueue(new MockResponse().setBody(EXPECTED));

        String rst = http(server.getPort()).get();

        assert rst != null;
        assert EXPECTED.equals(rst);
    }
}