Je suis un peu nouveau pour Mockito et je me demandais comment je pourrais remplacer une paire get/set.
Par exemple
public interface Dummy {
public String getString();
public void setString(String string);
}
Comment puis-je les faire se comporter correctement: si quelque part dans un test j'invoque setString("something");
, j'aimerais que getString()
renvoie "quelque chose". Est-ce faisable ou existe-t-il une meilleure façon de traiter de tels cas?
Je voulais aussi que le getter retourne le résultat du dernier appel de setter.
Ayant
class Dog
{
private Sound sound;
public Sound getSound() {
return sound;
}
public void setSound(Sound sound) {
this.sound = sound;
}
}
class Sound
{
private String syllable;
Sound(String syllable) {
this.syllable = syllable;
}
}
J'ai utilisé ce qui suit pour connecter le passeur au getter:
final Dog mockedDog = Mockito.mock(Dog.class, Mockito.RETURNS_DEEP_STUBS);
// connect getter and setter
Mockito.when(mockedDog.getSound()).thenCallRealMethod();
Mockito.doCallRealMethod().when(mockedDog).setSound(Mockito.any(Sound.class));
Je peux penser à trois approches possibles.
N'utilisez pas HttpServletRequest
directement dans votre application; faire une classe wrapper pour elle et avoir une interface pour la classe wrapper. Où que vous utilisiez actuellement HttpServletRequest
dans l'application, utilisez plutôt l'interface. Ensuite, dans le test, ayez une implémentation alternative de cette interface. Ensuite, vous n'avez pas besoin d'une maquette Mockito.
Ayez un champ dans votre classe de test qui stocke la valeur que vous avez définie à String
. Créez deux objets Mockito Answer
; un qui retourne la valeur de ce champ lorsque getString
est appelé, et un autre qui en définit la valeur lorsque setString
est appelé. Faites une maquette de la manière habituelle, et utilisez les deux réponses suivantes.
Créez une classe abstraite (qui peut être une classe interne statique de votre classe de test) qui implémente l'interface HttpServletRequest
, mais qui possède le champ que vous souhaitez définir, et définit les méthodes de lecture et de définition. Puis moquez la classe abstraite et transmettez Mockito.CALLS_REAL_METHODS comme réponse par défaut. Lorsque vous appelez le getter ou le passeur de la maquette, la vraie méthode entre en jeu, à savoir le comportement que vous souhaitez.
Espérons qu'une de ces trois solutions répondra à vos besoins.
J'avais ce problème, mais je ne voulais pas accepter la réponse acceptée, car cela mettrait fin à la moquerie de tous getters et setters dans ma fève. Tout ce que je voulais, c'était créer des talons pour un seul couple getter/setter, pas tous. En tant que tel, j'ai utilisé le code suivant.
@Mock
private Dummy mockDummy;
private final MutableObject<String> stringWrapper = new MutableObject<>();
public TestClass() {
MockitoAnnotations.initMocks(this);
doAnswer(invocationOnMock -> {
String injectedString = (String)invocationOnMock.getArguments()[0];
TestClass.this.stringWrapper.setValue(injectedString);
return null;
}).when(this.mockDummy).setString(any());
when(this.mockDummy.getString()).thenAnswer(
invocationOnMock -> TestClass.this.stringValue.getValue());
}
Le premier lambda implémente la méthode Answer<Void>
anonymous class ' answer()
. Ainsi, chaque fois que la méthode setter est exécutée par le code sous test, ce module de son créateur l'enregistre dans l'objet d'assistance MutableObject
. Cette valeur enregistrée qui a été définie peut ensuite être renvoyée par l'implémentation de lecture.