Ce n'est généralement pas une bonne idée de tester les demandes réelles du serveur. Voir this blog post pour une discussion intéressante sur le sujet. Selon l'auteur, en utilisant votre serveur réel est un problème parce que:
- Une autre pièce mobile qui peut échouer par intermittence
- nécessite une certaine expertise en dehors du domaine Android pour déployer le serveur et le tenir à jour
- difficiles à déclencher des cas d'erreur/bord
- exécution d'un test lent (toujours faire des appels HTTP)
Vous pouvez éviter tous les problèmes ci-dessus en utilisant un serveur fictif tel que MockWebServer d'OkHttp pour simuler des résultats de réponse réels. Par exemple:
@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();
}
Si vous avez besoin de simuler des retards de réseau, vous pouvez personnaliser votre réponse comme suit:
MockResponse response = new MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("Cache-Control", "no-cache")
.setBody("{}");
response.throttleBody(1024, 1, TimeUnit.SECONDS);
Vous pouvez également utiliser MockRetrofit
et NetworkBehavior
pour simuler les réponses de l'API. Voir here un exemple de la façon de l'utiliser. Enfin, si vous voulez simplement tester votre service Retrofit, le plus simple serait de créer une version simulée qui émet des résultats fictifs pour vos tests. Par exemple, si vous avez la GitHub
interface de service suivante:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
Vous pouvez ensuite créer le MockGitHub
suivant pour vos tests:
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);
}
}
Vous pouvez ensuite utiliser le MockGitHub
sur vos tests simuler les types des réponses que vous recherchez. Pour l'exemple complet, voir les implémentations de SimpleService et SimpleMockService pour ce Retrofit example.
Ayant dit tout cela, si vous devez absolument vous connecter au serveur réel, vous pouvez définir Retrofit pour travailler de manière synchrone avec une coutume ImmediateExecutor
:
public class ImmediateExecutor implements Executor {
@Override public void execute(Runnable command) {
command.run();
}
}
appliquent ensuite aux OkHttpClient
que vous utilisez lors de la construction du Retrofit :
OkHttpClient client = OkHttpClient.Builder()
.dispatcher(new Dispatcher(new ImmediateExecutor()))
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
//Your params
.build();
Toute votre réponse est basée sur la "simulation". Comme je l'ai dit sur le sujet de la question - je peux le faire. Mon projet est une bibliothèque qui fonctionnera avec l'API du serveur. La seule chose que j'ai besoin de tester - change sur le serveur, j'ai besoin de tester de vraies réponses. – AndrewS
J'ai proposé des alternatives parce que je pense que cela n'a pas de sens de tester sur un vrai serveur. Vous ne pouvez pas être sûr que le test fonctionnera dans différents endroits pour différents utilisateurs, vous ne pouvez pas facilement tester les problèmes de connexion, etc. Le serveur n'est pas quelque chose qui appartient à votre bibliothèque et ne devrait pas être traité comme tel, je pense. C'est pourquoi il est généralement préférable de tester le serveur _responses_ à la place. Si vous utilisez un 'MockWebServer', vous pouvez faire exécuter vos tests comme s'ils étaient connectés au vrai serveur. Votre bibliothèque ne connaitrait pas la différence. –
Si je fais la réponse de faux succès - j'obtiendrai le test de succès. Quel est le but de ce test? J'ai juste besoin de savoir quand la réponse du serveur a changé (par des tests), pour mettre à jour ma bibliothèque pour une nouvelle réponse. Je ne saurai jamais que quelque chose a changé si je fais une fausse réponse. – AndrewS