測試真實的服務器請求通常不是一個好主意。有關該主題的有趣討論,請參閱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