android - 如何在改造调用中引发异常
问题描述
我正在使用改造进行 api 调用,我想编写一个单元测试来检查它是否返回异常。
我想强制改造调用返回异常
资料库
class DataRepository @Inject constructor(
private val apiServiceInterface: ApiServiceInterface
) {
suspend fun getCreditReport(): CreditReportResponse {
try {
val creditReport = apiServiceInterface.getDataFromApi() // THIS SHOULD RETURN AN EXCEPTION AND I WANT TO CATCH THAT
return CreditReportResponse(creditReport, CreditReportResponse.Status.SUCCESS)
} catch (e: Exception) {
return CreditReportResponse(null, CreditReportResponse.Status.FAILURE)
}
}
}
ApiService接口
interface ApiServiceInterface {
@GET("endpoint.json")
suspend fun getDataFromApi(): CreditReport
}
我已经为 getCreditReport 编写了一个测试用例,它应该验证失败场景
@Test
fun getCreditReportThrowException() {
runBlocking {
val response = dataRepository.getCreditReport()
verify(apiServiceInterface, times(1)).getDataFromApi()
Assert.assertEquals(CreditReportResponse.Status.FAILURE, response.status)
}
}
所以要让上面的测试用例通过,我需要强制网络调用抛出异常
请建议
谢谢R
解决方案
实际上@Vaibhav Goyal 提供了一个很好的建议,让您的测试更容易。假设您正在使用 MVVM 结构,在您的测试用例中,您可以注入一个“模拟”服务类来模拟您在测试用例中定义的行为,因此图表将如下所示
由于我目前正在使用 mockk 库,因此您的代码库中的实际实现会有所不同。
@Test
fun test_exception() {
// given
val mockService = mockk<ApiServiceInterface>()
val repository = DataRepository(mockService)
every { mockService.getDataFromApi() } throws Exception("Error")
// when
val response = runBlocking {
repository.getCreditReport()
}
// then
verify(exactly = 1) { mockService.getDataFromApi }
assertEquals(CreditReportResponse.Status.FAILURE,response.status)
}
但是如果你想测试从 Retrofit 抛出的异常,那么你可能需要来自 square 的 mockServer 库来帮助你实现这个https://github.com/square/okhttp#mockwebserver
这个图表是这样的
您还必须设置模拟服务器才能这样做
@Test
fun test_exception_from_retrofit() {
// can put in the setup method / in junit4 rule or junit5 class
val mockWebServer = MockWebServer()
mockWebServer.start()
// given
val service = Retrofit.Builder()
.baseUrl(mockWebServer.url("/").toString())
.build()
.create(ApiServiceInterface::class)
val repository = DataRepository(service)
// when
mockWebServer.enqueue(MockResponse()
.setResponseCode(500)
.setBody("""{"name":"Tony}""") // you can read the json file content and then put it here
)
val response = runBlocking {
repository.getCreditReport()
}
// then
verify(exactly = 1) { mockService.getDataFromApi }
assertEquals(CreditReportResponse.Status.FAILURE,response.status)
// can put in tearDown / in junit4 rule or juni5 class
mockWebServer.shutdown()
}
所以你可以测试不同的异常,比如json格式无效、500状态码、数据解析异常
奖励积分
通常我会将测试json放在test目录下,并使其与api路径几乎相同,以便更好地维护
推荐阅读
- android - Activity 生命周期存储和恢复
- r - 在R中将字符变量更改为日期变量
- python - 如何将下拉小部件输出作为数据框?
- python - 如何将使用 SSH 从 Python 脚本运行的命令的输出存储到文件中?
- wordpress - 在 wwwroot 文件夹下安装 wordpress 容器
- android - 如何在具有所有手势的 SceneView 中使用 TransformableNode?
- excel - 如何使用下拉菜单自动填充其他工作表中的单元格范围
- python - 当我在函数/方法中有输入时,我该如何测试它?
- java - Pentaho 不能只用一个用户登录。所有其他用户工作正常
- ms-access - 如何使用具有多个值的一个参数进行查询?