J'utilise EasyMock (version 2.4) et TestNG pour écrire UnitTest.
J'ai un scénario suivant et je ne peux pas changer la façon dont la hiérarchie de classe est définie.
Je teste ClassB qui étend ClassA.
ClassB ressemble à ceci
public class ClassB extends ClassA {
public ClassB()
{
super("title");
}
@Override
public String getDisplayName()
{
return ClientMessages.getMessages("ClassB.title");
}
}
Code de classe
public abstract class ClassA {
private String title;
public ClassA(String title)
{
this.title = ClientMessages.getMessages(title);
}
public String getDisplayName()
{
return this.title;
}
}
Code de la classe ClientMessages
public class ClientMessages {
private static MessageResourse messageResourse;
public ClientMessages(MessageResourse messageResourse)
{
this.messageResourse = messageResourse;
}
public static String getMessages(String code)
{
return messageResourse.getMessage(code);
}
}
Code de la classe MessageResourse
public class MessageResourse {
public String getMessage(String code)
{
return code;
}
}
Test de la classe B
import static org.easymock.classextension.EasyMock.createMock;
import org.easymock.classextension.EasyMock;
import org.testng.Assert;
import org.testng.annotations.Test;
public class ClassBTest
{
private MessageResourse mockMessageResourse = createMock(MessageResourse.class);
private ClassB classToTest;
private ClientMessages clientMessages;
@Test
public void testGetDisplayName()
{
EasyMock.expect(mockMessageResourse.getMessage("ClassB.title")).andReturn("someTitle");
clientMessages = new ClientMessages(mockMessageResourse);
classToTest = new ClassB();
Assert.assertEquals("someTitle" , classToTest.getDisplayName());
EasyMock.replay(mockMessageResourse);
}
}
Lorsque j'exécute ce test, je reçois l'exception suivante:
Java.lang.IllegalStateException: définition du comportement manquante pour l'appel de méthode précédent getMessage ("title")} _
Lors du débogage, ce que j’ai trouvé est qu’il n’envisage pas l’appel de méthode fictive mockMessageResourse.getMessage ("ClassB.title")} [ tel qu’il a été appelé depuis le constructeur (création d’objets ClassB) .
Quelqu'un peut-il m'aider s'il vous plaît comment tester dans ce cas.
Merci.
Vous devez appeler EasyMock.replay(mock)
avant d'appeler la méthode testée. Après avoir appelé la méthode testée, vous pouvez appeler EasyMock.verify(mock)
pour vérifier que la maquette est appelée.
Ensuite, vous devez ajouter un autre appel expect
avec l’argument "title" puisque vous l’appelez deux fois.
Code:
EasyMock.expect(mockMessageResourse.getMessage("title")).andReturn("title");
EasyMock.expect(mockMessageResourse.getMessage("ClassB.title")).andReturn("someTitle");
EasyMock.replay(mockMessageResourse);
clientMessages = new ClientMessages(mockMessageResourse);
classToTest = new ClassB();
Assert.assertEquals("someTitle" , classToTest.getDisplayName());
EasyMock.verify(mockMessageResourse);
Dans mon cas, cela était dû à l'omission d'une spécification de valeur de retour (andReturn (...)) . http://www.smcmaster.com/2011/04/easymock-issue-1-missing -behavior.html pour plus de détails.
Vous devez passer votre appel à replay
après les appels expect
et avant vous utilisez votre maquette. Dans ce cas, vous devriez changer votre test en quelque chose comme ceci:
@Test
public void testGetDisplayName()
{
EasyMock.expect(mockMessageResourse.getMessage("ClassB.title")).andReturn("someTitle");
EasyMock.replay(mockMessageResourse);
clientMessages = new ClientMessages(mockMessageResourse);
classToTest = new ClassB();
Assert.assertEquals("someTitle" , classToTest.getDisplayName());
}
Cela peut avoir différentes causes (someMock
est le nom de votre objet fictif dans cette réponse) . D'un côté, il se peut que vous deviez attendre l'appel via
expect(someMock.someMethod(anyObject()).andReturn("some-object");
comme dans La réponse de Reda . Il se peut également que vous ayez oublié d'appeler replay(someMock)
avant d'utiliser la maquette, comme vous pouvez le voir dans la réponse de Julien Rentrop .
Une dernière chose possible qui n’a pas été mentionnée ici est que vous avez utilisé la maquette quelque part avant dans un test et que vous avez oublié de réinitialiser la maquette via reset(someMock)
.
Cela peut arriver si vous avez plusieurs tests unitaires comme celui-ci:
private Object a = EasyMock.createMock(Object.class);
@Test
public void testA() throws Exception {
expect(a.someThing()).andReturn("hello");
replay(a);
// some test code and assertions etc. here
verify(a);
}
@Test
public void testB() throws Exception {
expect(a.someThing()).andReturn("hello");
replay(a);
// some test code and assertions etc. here
verify(a);
}
Cela échouera sur un test avec IllegalStateException, car le faux a n'a pas été réinitialisé avant d'être utilisé lors du prochain test. Pour le résoudre, vous pouvez procéder comme suit:
private Object a = EasyMock.createMock(Object.class);
@Test
public void testA() throws Exception {
expect(a.someThing()).andReturn("hello");
replay(a);
// some test code and assertions etc. here
verify(a);
}
@Test
public void testB() throws Exception {
expect(a.someThing()).andReturn("hello");
replay(a);
// some test code and assertions etc. here
verify(a);
}
@After
public void tearDown() throws Exception {
reset(a); // reset the mock after each test
}