Confus comment utiliser Mockito pour android test
Je suis en train d'écrire un test unitaire pour mon application android, mais ont du mal à faire ce que je veux avec mockito. Ce est utilisé en conjonction avec Robolectric que j'ai fonctionne très bien et ont démontré que les tests unitaires du travail.
Je veux tester si oui ou non un bouton permet d'ouvrir une nouvelle activité, selon qu'il y a quelques périphérique bluetooth connecté. Évidemment, aucun périphérique n'est connecté avec le bluetooth dans mon test, mais je tiens à faire semblant comme s'il en est. L'état de la connexion bluetooth est stocké dans ma classe d'Application. Il n'est pas accessible au public méthode pour modifier cette valeur.
Donc, fondamentalement, la logique de l'application est comme ceci:
HomeActivity.java:
//this gets called when the button to open the list is clicked.
public void openListActivity(View button) {
MyApplication myApplication = (MyApplication) getApplication();
if (myApplication.isDeviceConnected() {
startActivity(new intent(this, ListActivity.class));
}
}
Afin de tester ce que je n'ai suivantes:
TestHomeActivity.java:
@Test
public void buttonShouldOpenListIfConnected() {
FlexApplication mockedApp = Mockito.mock(MyApplication.class);
Mockito.when(mockedApp.isDeviceConnected()).thenReturn(true);
//listViewButton was setup in @Before
listViewButton.performClick();
ShadowActivity shadowActivity = Robolectric.shadowOf(activity);
Intent intent = shadowActivity.getNextStartedActivity();
assertNotNull(intent); //this fails because no new activity was opened. I debugged this and found that isDeviceConnected returned false.
ShadowIntent shadowIntent = Robolectric.shadowOf(intent);
assertThat(shadowIntent.getComponent().getClassName(), equalTo(ListActivity.class.getName()));
}
Donc mon test de l'unité échoue parce que l'appel (de l'activité) à isDeviceConnected renvoie la valeur false, même si je pensée je l'ai dit à retourner true avec la simulation de cadre. Je veux que mon test de cette méthode retourne true si. N'est-ce pas ce que mockito ne ou suis-je totalement tort sur la façon d'utiliser mockito?
Voir aussi Comment mettre en place Mockito, à se moquer de classe pour Android unité de test
OriginalL'auteur Matt Wolfe | 2012-12-20
Vous devez vous connecter pour publier un commentaire.
C'est comment mockito fonctionne, mais le problème est: est-ce votre
listViewButton
à l'aide de votremockedApp
? Semble pas, parce que vous êtes en train de créermockedApp
à la méthode de test et de ne jamais mettre n'importe où. Mockito ne se moque pas de la méthode des appels de toutes les instances deApplication
, seulement de ce que vous avez déclaré qu'un simulacre.Personnellement, je ne sais pas comment android fonctionne avec le
Application
classe, mais vous devrez les régler quelque sorte listView utiliser votremockedApp
plutôt que ce qu'il reçoit normalement.MODIFIER
Après la mise à jour de question, vous pouvez transformer votre
getApplication
dans une méthode protégée,espion
vouslistViewButton
et le faire revenir votremockedApp
. Qui sent un peu mauvais, mais c'est un moyen si vous ne pouvez pas régler votre application se moquaient de l'objet àlistViewButton
.EDIT2
Exemple d'utilisation de l'espion dans votre test à l'aide de
BDDMockito
pour des raisons de lisibilité 🙂Après cela, votre test doit fonctionner comme prévu. Mais je confirme: l'Utilisation
spy
seulement si vous ne pouvez pas injecter,mockedApp
à l'intérieur de HomeActivity.si spy objets sont une odeur de code, ce serait une meilleure solution? Devrais-je essayer d'Injecter de l'Application? Ajouter une définition pour l'application? Déplacer la logique qui gère la connectivité de l'état à une autre classe? Je ne suis pas actuellement à l'aide d'une injection de dépendance cadre, mais je pourrais peut-être. Je n'aime vraiment pas le bien que des méthodes d'écriture utilisé juste pour le tester, mais c'est peut-être un mal nécessaire.
Vous pourrait injecter de l'application. Si par setter ou d'un constructeur, vous avez à décider. Je préfère par le constructeur. Si vous définissez getapplication protégé, annoté avec les goyaves @VisibleForTesting. Il est bon de ne délimitent
OriginalL'auteur Caesar Ralf
Se moquaient de votre version n'est pas appelé.
Voir à cet appel,
getApplication()
? (ci-dessous). C'est le retour d'une véritable copie de votre MyApplication classe, de ne pas se moquaient de votre version. Vous auriez besoin d'intercepter legetApplication()
appeler et passer des dans votre moqué de l'objet Application.Je ne suis pas sûr que c'est possible avec Mockito. Avez-vous essayé la personnalisation de la ShadowActivity#getApplication() la méthode?
Utiliser le setter de l'injection de dépendance, c'est facile (nous sommes à l'aide de RoboGuice). Donc, fondamentalement, ont le champ d'application qui est par défaut réel de la demande, mais ont certaines protégées setter pour injecter de l'application au lieu
OriginalL'auteur c2knaps