Se moquant de lecture / définition de la méthode de l'Interface avec Mockito
Je suis en train de tester mon application avec jUnit et Mockito et je suis en cours d'exécution dans des problèmes. Voici un exemple simplifié qui explique le problème
Interface KeyValueInterface
public interface KeyValueInterface {
public abstract String getKey();
public abstract void setKey(String key);
public abstract String getValue();
public abstract void setValue(String value);
}
Classe KeyValueImpl
public class KeyValueImpl implements KeyValueInterface {
private String key;
private String value;
@Override
public String getKey() {
return key;
}
@Override
public void setKey(String key) {
this.key = key;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
}
Classe avec "logique d'entreprise"
public class ValueFinder {
public KeyValueInterface findValueForKey(KeyValueInterface keyValue){
keyValue.setValue("foo");
return keyValue;
}
}
de la classe de Test jUnit
import static org.junit.Assert.*;
import org.junit.Test;
import org.mockito.Mockito;
public class ValueFinderTest {
@Test
public void testNotMocked() {
KeyValueInterface keyValue = new KeyValueImpl();
keyValue = (new ValueFinder()).findValueForKey(keyValue);
assertEquals("foo", keyValue.getValue()); //works fine
}
@Test
public void testMocked1() {
KeyValueInterface keyValue = Mockito.mock(KeyValueInterface.class);
keyValue = (new ValueFinder()).findValueForKey(keyValue);
assertEquals("foo", keyValue.getValue()); //java.lang.AssertionError:
//expected:<foo> but
//was:<null>
}
@Test
public void testMocked2() {
KeyValueInterface keyValue = Mockito.mock(KeyValueInterface.class);
keyValue = (new ValueFinder()).findValueForKey(keyValue);
Mockito.when(keyValue.getValue()).thenCallRealMethod();
Mockito.doCallRealMethod().when(keyValue).setValue(Mockito.any(String.class));
assertEquals("foo", keyValue.getValue()); //org.mockito.exceptions.base.MockitoException:
//Cannot call real method
//on java interface.
//Interface does not have
//any implementation!
//Calling real methods is
//only possible when
//mocking concrete classes.
}
}
Mon problème est que j'ai besoin pour se moquer de KeyValue pour des raisons techniques qui sont hors de mon contrôle. Donc je ne peux pas juste aller avec la méthode testNotMocked(). Également pour des raisons techniques indépendantes de ma volonté, j'ai de se moquer de l'interface (et non pas la classe).
Est-il un moyen pour y parvenir?
Merci beaucoup.
Vous devez vous connecter pour publier un commentaire.
Si vous deviez écrire la javadoc de la méthode que vous faites des tests, sans même savoir ce que l'une des méthodes de l'interface sont en train de faire, vous devez écrire le suivant:
Vous ne devriez pas même supposer que
getValue()
retourne la valeur qui a été mis en avant. Ce n'est certainement pas ce que la simulation va le faire, depuis la maquette n'a pas faire autre chose que ce que vous lui dites de faire. Tout ce que vous devez faire est de tester le contrat de votre méthode, sans présumer de rien à propos de la mise en œuvre de l'interface. Si votre test doit êtreMaquette ne sait rien au sujet de votre Impl classe. Donc, il suffit de le faire soit
verify
poursetValue
ou de l'utilisation de l'espion à callreal méthodes.si vous cochez la Mockito API pour la simulation de la méthode ci-dessous, vous pouvez voir qu'il crée de se moquer de l'objet de la classe ou de l'interface.
Donc l'erreur pour la première méthode testMocked1() est valide. ce que vous êtes en train de faire, il se moque de l'impl pour que l'interface indirectement. Ainsi, lorsque vous vous que toutes les méthodes get se moquèrent de lui et depuis getValue() renvoie une Chaîne de sorte que la valeur par défaut de la Chaîne est nulle si une valeur NULL est arriver retourné. Utilisation ReflectionUtils comme ci-dessous pour définir la valeur de la clé directement
et ne ci-dessous dans votre méthode testMocked1()
De même pour la 2ème méthode testMocked2() faire de même en utilisant reflectionutils pour définir la valeur et utiliser les méthodes de l'api de Mockito
Utiliser quand/puis pour configurer votre maquette.
Voir http://www.baeldung.com/mockito-behavior