Mockito - "Recherché mais non invoqué; Cependant il y avait d'autres interactions avec cette fausse "erreur"
Je suis de vérifier qu'une fonction a été appelée à l'aide de Mockito, mais Mockito est de me dire que la fonction je suis la vérification n'a jamais été appelé et que d'autres fonctions ont été appelés. Mais il me semble que je vais appeler la bonne fonction...
Voici la trace de la pile pour l'erreur que je reçois:
Wanted but not invoked:
relationshipAutoIndexer.getAutoIndex();
-> at org.whispercomm.manes.server.graph.DataServiceImplTest.testInitIndices(DataServiceImplTest.java:117)
However, there were other interactions with this mock:
-> at org.whispercomm.manes.server.graph.DataServiceImpl.updateIndexProperties(DataServiceImpl.java:136)
-> at org.whispercomm.manes.server.graph.DataServiceImpl.updateIndexProperties(DataServiceImpl.java:144)
-> at org.whispercomm.manes.server.graph.DataServiceImpl.updateIndexProperties(DataServiceImpl.java:148)
-> at org.whispercomm.manes.server.graph.DataServiceImpl.updateIndexProperties(DataServiceImpl.java:149)
-> at org.whispercomm.manes.server.graph.DataServiceImpl.initIndices(DataServiceImpl.java:121)
at org.whispercomm.manes.server.graph.DataServiceImplTest.testInitIndices(DataServiceImplTest.java:117)
Il se produit à
verify(relAutoIndexer).getAutoIndex();
de la classe de test de code ci-dessous.
Voici mon code (j'ai tendance à laisser les choses par accident. Merci de me demander le code vous pensez que je suis absent et je vais l'ajouter):
public DataServiceImpl(GraphDatabaseService graphDb) {
super();
this.graphDb = graphDb;
unarchivedParent = new UnarchivedParent(graphDb.createNode());
archivedParent = new ArchivedParent(graphDb.createNode());
packetParent = new PacketParent(graphDb.createNode());
userParent = new UserParent(graphDb.createNode());
this.initIndices();
}
/**
* Initializes the node and relationship indexes.
*
* Updates the set of indexed properties to match {@link DataServiceImpl}
* .NODE_KEYS_INDEXABLE and {@link DataServiceImpl}.REL_KEYS_INDEXABLE.
*
* Note: auto indices can also be configured at database creation time and
* just retrieved at runtime. We might want to switch to that later.
*/
private void initIndices() {
/* Get the auto-indexers */
AutoIndexer<Node> nodeAutoIndexer = this.graphDb.index()
.getNodeAutoIndexer();
AutoIndexer<Relationship> relAutoIndexer = this.graphDb.index()
.getRelationshipAutoIndexer();
this.updateIndexProperties(nodeAutoIndexer,
DataServiceImpl.NODE_KEYS_INDEXABLE);
this.nodeIndex = nodeAutoIndexer.getAutoIndex();
this.updateIndexProperties(relAutoIndexer,
DataServiceImpl.REL_KEYS_INDEXABLE);
this.relIndex = relAutoIndexer.getAutoIndex();
}
/**
* Sets the indexed properties of an {@link AutoIndexer} to the specified
* set, removing old properties and adding new ones.
*
* @param autoIndexer
* the AutoIndexer to update.
* @param properties
* the properties to be indexed.
* @return autoIndexer, this given AutoIndexer (useful for chaining calls.)
*/
private <T extends PropertyContainer> AutoIndexer<T> updateIndexProperties(
AutoIndexer<T> autoIndexer, Set<String> properties) {
Set<String> indexedProps = autoIndexer.getAutoIndexedProperties();
//Remove unneeded properties.
for (String prop : difference(indexedProps, properties)) {
autoIndexer.stopAutoIndexingProperty(prop);
}
//Add new properties.
for (String prop : difference(properties, indexedProps)) {
autoIndexer.startAutoIndexingProperty(prop);
}
//Enable the index, if needed.
if (!autoIndexer.isEnabled()) {
autoIndexer.setEnabled(true);
}
return autoIndexer;
}
Et voici le code pour la classe de test:
@Before
public void setup() {
nA = mock(Node.class);
nB = mock(Node.class);
packetA = new PacketWrapper(nA);
packetB = new PacketWrapper(nB);
RelA = mock(Relationship.class);
RelB = mock(Relationship.class);
graphDb = mock(GraphDatabaseService.class);
nodeAutoIndexer = (AutoIndexer<Node>) mock(AutoIndexer.class);
relAutoIndexer = mock(RelationshipAutoIndexer.class);
}
@After
public void tearDown() {
packetA = null;
packetB = null;
}
/*
* ---------------- Test initIndices() ---------------
*/
//TODO
@Test
public void testInitIndices() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
IndexManager indexManager = mock(IndexManager.class);
when(graphDb.index()).thenReturn(indexManager);
when(indexManager.getNodeAutoIndexer()).thenReturn(nodeAutoIndexer);
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer);
dataService = new DataServiceImpl(graphDb);
verify(nodeAutoIndexer, atLeastOnce()).getAutoIndex();
verify(relAutoIndexer).getAutoIndex();
}
source d'informationauteur gsingh2011
Vous devez vous connecter pour publier un commentaire.
Mockito, jusqu'à la version 1.8.5, avait un bug dans le cas du polymorphisme de l'expédition. Il a été corrigé et est disponible dans la première version release candidate de la version 1.9.0. Voir problème de 200.
Alors, comment se fait-il dans votre base de code. Remarque vous se moquant de ces deux classes
AutoIndexer
arriver à être un parent générique de l'interface, dans cette interface, il ya cette méthodeReadableIndex<T> getAutoIndex()
.RelationshipAutoIndexer
est un sous-type de laAutoInexer
où la partie générique est fixé àRelationship
et de remplacer lesgetAutoIndex()
méthode pour retourner covariante du typeReadableRelationshipIndex
.Voir AutoIndexer et RelationshipIndexer.
Bien, dans votre code d'appel vous avez ces lignes:
Les deux
nodeAutoIndex
dans votre code de production et la simulation denodeAutoIndexer
dans votre code de test ont une référence de typeAutoIndexer<Node>
donc il n'y a pas de problème pour polymorphe de l'expédition.Cependant
relAutoIndex
dans votre code de production est référencé par le type deAutoIndexer<Relationship>
et la simulation derelAutoIndexer
dans votre code de test est référencé par le type deRelationshipAutoIndexer
, de sorte que le mauvais appel est enregistré sur la maquette, puis la vérification échoue.Votre solution est soit pour mettre à niveau le mockito version; la 1.9.0 RC1 est très stable et une version finale devrait être à venir à votre façon. Ou vous pouvez migrer votre type de référence (dans votre code de production) à partir de :
:
Quelques autres remarques.
Vous n'avez pas réellement besoin d'écrire un après la méthode ici comme JUnit crée une nouvelle instance à chaque exécution de méthode, de sorte que votre méthode ajoute juste le code qui sera fait de toute façon. Remarque ce n'est pas le cas avec TestNG.
Au lieu de créer votre se moque en avant la méthode, vous pouvez utiliser Mockito annotations. N'oubliez pas le coureur.
Par exemple :
Le buter code est un peu moche pour plusieurs raisons.
Pourquoi ne pas écrire cela dans une manière plus propre; par exemple le référencement
indexManager
dans les deux cas :Ou de ne pas faire référence à tous les
Aussi d'avoir une maquette qui retourne un simulacre est généralement le signe d'une conception de l'odorat. Vous êtes à la transgression de la loi de Déméter, et de briser cela signifie que vous ferez l'expérience difficile de test, de mauvais entretien et difficile évolution. Quand je dis que vous pourriez m'entendre murmurer également (sans les syllogismes) : il va vous coûter de l'argent. Ne pas écrire de code legacy! Si vous pratiquer le TDD ou BDD, vous permettra d'identifier ces problèmes au moment de la conception de votre propre code, ce qui est excellent pour les prévenir.
En utilisant les méthodes statiques, vous pouvez écrire ce
Ou à l'aide de l'annotation, vous pouvez écrire ceci :
Et le buter :