使用 Mock 测试
没有用过 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);
}
}