android mockito retrofit2,使用Retrofit2和Mockito或Robolectric进行Android单元测试

90

It is generally not a good idea to test real server requests. See this blog post for an interesting discussion on the topic. According to the author, using your real server is a problem because:

测试真实服务器请求通常不是一个好主意。有关该主题的有趣讨论,请参阅此博客文章。据作者说,使用真正的服务器是一个问题,因为:

Another moving piece that can intermittently fail

另一个可以间歇性失效的移动件

Requires some expertise outside of the Android domain to deploy the server and keep it updated

需要Android域之外的一些专业知识来部署服务器并使其保持更新

Difficult to trigger error/edge cases

难以触发错误/边缘情况

Slow test execution (still making HTTP calls)

测试执行缓慢(仍在进行HTTP调用)

You can avoid all the issues above by using a mock server such as OkHttp's MockWebServer to simulate real response results. For example:

您可以使用模拟服务器(如OkHttp的MockWebServer)来模拟真实的响应结果,从而避免上述所有问题。例如:

@Test

public void test() throws IOException {

MockWebServer mockWebServer = new MockWebServer();

Retrofit retrofit = new Retrofit.Builder()

.baseUrl(mockWebServer.url("").toString())

//TODO Add your Retrofit parameters here

.build();

//Set a response for retrofit to handle. You can copy a sample

//response from your server to simulate a correct result or an error.

//MockResponse can also be customized with different parameters

//to match your test needs

mockWebServer.enqueue(new MockResponse().setBody("your json body"));

YourRetrofitService service = retrofit.create(YourRetrofitService.class);

//With your service created you can now call its method that should

//consume the MockResponse above. You can then use the desired

//assertion to check if the result is as expected. For example:

Call call = service.getYourObject();

assertTrue(call.execute() != null);

//Finish web server

mockWebServer.shutdown();

}

If you need to simulate network delays, you can customize your response as follows:

如果您需要模拟网络延迟,可以按如下方式自定义响应:

MockResponse response = new MockResponse()

.addHeader("Content-Type", "application/json; charset=utf-8")

.addHeader("Cache-Control", "no-cache")

.setBody("{}");

response.throttleBody(1024, 1, TimeUnit.SECONDS);

Alternatively, you can use MockRetrofit and NetworkBehavior to simulate API responses. See here an example of how to use it.

或者,您可以使用MockRetrofit和NetworkBehavior来模拟API响应。在这里查看如何使用它的示例。

Finally, if you just want to test your Retrofit Service, the easiest would be to create a mock version of it that emits mock results for your tests. For example, if you have the following GitHub service interface:

最后,如果您只想测试您的Retrofit服务,最简单的方法是创建一个模拟版本,为您的测试发出模拟结果。例如,如果您有以下GitHub服务接口:

public interface GitHub {

@GET("/repos/{owner}/{repo}/contributors")

Call> contributors(

@Path("owner") String owner,

@Path("repo") String repo);

}

You can then create the following MockGitHub for your tests:

然后,您可以为测试创建以下MockGitHub:

public class MockGitHub implements GitHub {

private final BehaviorDelegate delegate;

private final Map>> ownerRepoContributors;

public MockGitHub(BehaviorDelegate delegate) {

this.delegate = delegate;

ownerRepoContributors = new LinkedHashMap<>();

// Seed some mock data.

addContributor("square", "retrofit", "John Doe", 12);

addContributor("square", "retrofit", "Bob Smith", 2);

addContributor("square", "retrofit", "Big Bird", 40);

addContributor("square", "picasso", "Proposition Joe", 39);

addContributor("square", "picasso", "Keiser Soze", 152);

}

@Override public Call> contributors(String owner, String repo) {

List response = Collections.emptyList();

Map> repoContributors = ownerRepoContributors.get(owner);

if (repoContributors != null) {

List contributors = repoContributors.get(repo);

if (contributors != null) {

response = contributors;

}

}

return delegate.returningResponse(response).contributors(owner, repo);

}

}

You can then use the MockGitHub on your tests to simulate the kinds of responses you are looking for. For the full example, see the implementations of the SimpleService and SimpleMockService for this Retrofit example.

然后,您可以在测试中使用MockGitHub来模拟您要查找的各种响应。有关完整示例,请参阅此Retrofit示例的SimpleService和SimpleMockService的实现。

Having said all this, if you absolutely must connect to the actual server, you can set Retrofit to work synchronously with a custom ImmediateExecutor:

说了这么多,如果你绝对必须连接到实际的服务器,你可以设置Retrofit与自定义ImmediateExecutor同步工作:

public class ImmediateExecutor implements Executor {

@Override public void execute(Runnable command) {

command.run();

}

}

Then apply it to the OkHttpClient you use when building the Retrofit:

然后将其应用于构建Retrofit时使用的OkHttpClient:

OkHttpClient client = OkHttpClient.Builder()

.dispatcher(new Dispatcher(new ImmediateExecutor()))

.build();

Retrofit retrofit = new Retrofit.Builder()

.client(client)

//Your params

.build();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值