测试真实的服务器请求通常不是一个好主意。有关该主题的有趣讨论,请参阅this blog post。据笔者,使用您的真实服务器是一个问题,因为:
- 另一个运动件,可以间歇性地失败
- 所需的Android域之外的一些专业知识来部署服务器,并保持更新
- 难以触发错误/边缘情况
- 慢速测试执行(仍使HTTP调用)
您可以通过使用模拟服务器(如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<YourObject> call = service.getYourObject();
assertTrue(call.execute() != null);
//Finish web server
mockWebServer.shutdown();
}
如果您需要模拟网络延迟,你可以定制你的回应如下:
MockResponse response = new MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("Cache-Control", "no-cache")
.setBody("{}");
response.throttleBody(1024, 1, TimeUnit.SECONDS);
或者,你可以使用MockRetrofit
和NetworkBehavior
模拟API响应。请参阅here如何使用它的示例。
最后,如果你只是想测试你的改进服务,最简单的方法是创建一个模拟版本,发布模拟测试结果。例如,如果您有以下GitHub
服务接口:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
然后,您可以创建你的测试以下MockGitHub
:
public class MockGitHub implements GitHub {
private final BehaviorDelegate<GitHub> delegate;
private final Map<String, Map<String, List<Contributor>>> ownerRepoContributors;
public MockGitHub(BehaviorDelegate<GitHub> 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<List<Contributor>> contributors(String owner, String repo) {
List<Contributor> response = Collections.emptyList();
Map<String, List<Contributor>> repoContributors = ownerRepoContributors.get(owner);
if (repoContributors != null) {
List<Contributor> contributors = repoContributors.get(repo);
if (contributors != null) {
response = contributors;
}
}
return delegate.returningResponse(response).contributors(owner, repo);
}
}
然后,您可以使用MockGitHub
上的测试,以模拟种您正在寻找的回复。有关完整示例,请参阅的SimpleService和SimpleMockService的实现。
说了这么多,如果你绝对必须连接到实际的服务器,你可以设置改造与定制ImmediateExecutor
同步工作:
public class ImmediateExecutor implements Executor {
@Override public void execute(Runnable command) {
command.run();
}
}
然后将它应用到OkHttpClient
您在构建改造时使用:
OkHttpClient client = OkHttpClient.Builder()
.dispatcher(new Dispatcher(new ImmediateExecutor()))
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
//Your params
.build();
所有的答案都基于“模拟”。正如我在问题上所说的 - 我可以做到这一点。我的项目是一个可以与服务器API协同工作的库。我需要测试的唯一事情就是在服务器上进行更改,我需要测试真实的响应。 – AndrewS
我提供了替代方案,因为我认为在真实服务器上测试是没有意义的。您无法确定测试将在不同用户的不同位置工作,您无法轻松测试连接问题等等。服务器不属于你的图书馆,我认为不应该这样对待。这就是为什么通常更好地测试服务器_responses_的原因。如果你使用'MockWebServer',你可以运行你的测试,就像连接到真实的服务器一样。你的图书馆不知道其中的差别。 –
如果我做出假冒成功的回应 - 我会得到成功的考验。这个测试有什么意义?我只需要知道服务器响应何时更改(通过测试),以更新我的库以获取新响应。如果我做出虚假的回应,我永远不会知道有什么改变。 – AndrewS