MyBookshelf单元测试:MockWebServer使用指南
测试环境配置
在Android项目中集成MockWebServer需在build.gradle添加依赖。MyBookshelf使用OkHttp作为网络客户端,测试模块需包含:
testImplementation 'com.squareup.okhttp3:mockwebserver:4.9.3'
testImplementation 'junit:junit:4.13.2'
基础使用示例
创建测试类验证网络请求处理逻辑:
public class BookApiTest {
private MockWebServer server;
private BookApiService apiService;
@Before
public void setup() throws IOException {
server = new MockWebServer();
server.start();
// 配置 Retrofit 指向本地服务器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(BookApiService.class);
}
@Test
public void testGetBookDetails() throws IOException, InterruptedException {
// 模拟服务器响应
server.enqueue(new MockResponse()
.setResponseCode(200)
.setBody("{\"id\":1,\"title\":\"Android Testing Guide\"}")
.addHeader("Content-Type", "application/json"));
// 执行测试请求
Call<BookDetail> call = apiService.getBookDetail(1);
Response<BookDetail> response = call.execute();
// 验证响应内容
assertNotNull(response.body());
assertEquals("Android Testing Guide", response.body().getTitle());
// 验证请求参数
RecordedRequest request = server.takeRequest();
assertEquals("/books/1", request.getPath());
assertEquals("GET", request.getMethod());
}
@After
public void teardown() throws IOException {
server.shutdown();
}
}
高级场景模拟
1. 模拟错误响应
@Test
public void testNetworkErrorHandling() throws IOException {
server.enqueue(new MockResponse()
.setResponseCode(500)
.setBody("Internal Server Error"));
Call<BookDetail> call = apiService.getBookDetail(999);
Response<BookDetail> response = call.execute();
assertFalse(response.isSuccessful());
assertEquals(500, response.code());
}
2. 模拟延迟响应
@Test
public void testTimeoutHandling() throws IOException {
server.enqueue(new MockResponse()
.setBodyDelay(3, TimeUnit.SECONDS) // 模拟3秒延迟
.setBody("{\"id\":1,\"title\":\"Delayed Response\"}"));
// 配置超时时间为2秒的OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.SECONDS)
.build();
// 执行测试并验证超时异常
try {
Call<BookDetail> call = apiService.getBookDetail(1);
call.execute();
fail("Should throw timeout exception");
} catch (SocketTimeoutException e) {
// 预期异常
}
}
测试资源管理
测试中使用的JSON响应模板建议放在:
- 测试数据目录
可通过以下方式加载测试数据:
private String loadJsonFromResource(String fileName) throws IOException {
InputStream is = getClass().getClassLoader().getResourceAsStream(fileName);
return new BufferedReader(new InputStreamReader(is))
.lines().collect(Collectors.joining("\n"));
}
// 使用示例
String mockResponse = loadJsonFromResource("book_detail_response.json");
server.enqueue(new MockResponse().setBody(mockResponse));
最佳实践
- 每个测试独立:确保测试方法间无状态共享
- 验证请求完整性:检查HTTP方法、头信息、参数
- 模拟各种场景:成功响应、错误码、网络异常、超时
- 使用真实解析逻辑:避免在测试中重写JSON解析代码
- 资源清理:确保
@After中关闭MockWebServer
常见问题解决
- 端口冲突:使用
server.start(0)自动分配端口 - 异步测试:配合
CountDownLatch处理异步回调 - HTTPS测试:使用
MockWebServer.useHttps()配置SSL
更多测试示例可参考Android官方文档和OkHttp测试指南
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



