Donc, je crée un objet fictif en tant que variable statique au niveau de la classe, comme suit ... Dans un test, je veux que Foo.someMethod()
renvoie une certaine valeur, tandis que dans un autre test, je veux qu'il renvoie un valeur différente. Le problème que j'ai, c'est qu'il semble que j'ai besoin de reconstruire les simulacres pour que cela fonctionne correctement. J'aimerais éviter de reconstruire les simulacres et utiliser simplement les mêmes objets dans chaque test.
class TestClass {
private static Foo mockFoo;
@BeforeClass
public static void setUp() {
mockFoo = mock(Foo.class);
}
@Test
public void test1() {
when(mockFoo.someMethod()).thenReturn(0);
TestObject testObj = new TestObject(mockFoo);
testObj.bar(); // calls mockFoo.someMethod(), receiving 0 as the value
}
@Test
public void test2() {
when(mockFoo.someMethod()).thenReturn(1);
TestObject testObj = new TestObject(mockFoo);
testObj.bar(); // calls mockFoo.someMethod(), STILL receiving 0 as the value, instead of expected 1.
}
}
Dans le deuxième test, je reçois toujours 0 comme valeur lorsque testObj.bar () est appelé ... Quel est le meilleur moyen de résoudre ce problème? Notez que je sais que je pourrais utiliser un modèle différent de Foo
dans chaque test. Toutefois, je dois chaîner plusieurs requêtes à partir de mockFoo
, ce qui signifie que je devrais effectuer l'enchaînement dans chaque test.
Tout d'abord, ne faites pas la maquette statique. Faites-en un champ privé. Il suffit de mettre votre classe setUp dans le @Before
pas @BeforeClass
. Il peut être couru un tas, mais c'est bon marché.
Deuxièmement, la façon dont vous l'avez maintenant est la bonne façon d'obtenir une maquette pour renvoyer quelque chose de différent en fonction du test.
Vous pouvez également Appels consécutifs stub (# 10 dans 2.8.9 api). Dans ce cas, vous utiliseriez plusieurs appels thenReturn ou un appel thenReturn avec plusieurs paramètres (varargs).
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
public class TestClass {
private Foo mockFoo;
@Before
public void setup() {
setupFoo();
}
@Test
public void testFoo() {
TestObject testObj = new TestObject(mockFoo);
assertEquals(0, testObj.bar());
assertEquals(1, testObj.bar());
assertEquals(-1, testObj.bar());
assertEquals(-1, testObj.bar());
}
private void setupFoo() {
mockFoo = mock(Foo.class);
when(mockFoo.someMethod())
.thenReturn(0)
.thenReturn(1)
.thenReturn(-1); //any subsequent call will return -1
// Or a bit shorter with varargs:
when(mockFoo.someMethod())
.thenReturn(0, 1, -1); //any subsequent call will return -1
}
}
Pour tous ceux qui cherchent à renvoyer quelque chose, puis une autre exception de lancement d'appel:
when(mockFoo.someMethod())
.thenReturn(obj1)
.thenReturn(obj2)
.thenThrow(new RuntimeException("Fail"));
ou
when(mockFoo.someMethod())
.thenReturn(obj1, obj2)
.thenThrow(new RuntimeException("Fail"));
Pour tous ceux qui utilisent spy () et la méthode doReturn () à la place de la méthode when ():
voici ce dont vous avez besoin pour renvoyer un objet différent sur différents appels:
doReturn(obj1).doReturn(obj2).when(this.client).someMethod();
Ou encore plus propre:
when(mockFoo.someMethod()).thenReturn(obj1, obj2);