java.lang.IllegalStateException:前面的方法调用getMessage(“title”)缺少行为定义

我正在使用EasyMock(版本2.4)和TestNG来编写UnitTest。

我有一个以下场景,我不能改变定义类层次结构的方式。

我正在测试扩展ClassA的ClassB。

ClassB看起来像这样

public class ClassB extends ClassA { public ClassB() { super("title"); } @Override public String getDisplayName() { return ClientMessages.getMessages("ClassB.title"); } } 

ClassA代码

 public abstract class ClassA { private String title; public ClassA(String title) { this.title = ClientMessages.getMessages(title); } public String getDisplayName() { return this.title; } } 

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); } } 

MessageResourse类代码

 public class MessageResourse { public String getMessage(String code) { return code; } } 

测试ClassB

 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); } } 

当我运行此测试时,我遇到以下exception:

java.lang.IllegalStateException:前面的方法调用getMessage(“title”)缺少行为定义

在调试我发现的内容时,它不考虑mock方法调用mockMessageResourse.getMessage(“ClassB.title”),因为它已经从构造器调用(ClassB对象创建)。

任何人都可以帮我在这种情况下如何测试。

谢谢。

在调用测试方法之前,您需要调用EasyMock.replay(mock) 。 在调用测试方法之后,您可以调用EasyMock.verify(mock)来validation调用mock。

接下来,您需要使用“title”参数添加另一个expect调用,因为您调用它两次。

码:

 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); 

在我的情况下,它是由于遗漏了返回值规范(andReturn(…))。 http://www.smcmaster.com/2011/04/easymock-issue-1-missing-behavior.html了解更多详情。

这可能有多种原因( someMock是此答案中someMock对象的名称)。 一方面,您可能需要通过电话预期

 expect(someMock.someMethod(anyObject()).andReturn("some-object"); 

就像在Reda的回答中一样 。 也可能是你在使用模拟之前忘记调用replay(someMock) ,就像你在Julien Rentrop的回答中看到的那样。

这里没有提到的最后一件事是你在测试之前在其他地方使用了模拟,忘了通过reset(someMock)重置模拟。

如果你有多个这样的unit testing,就会发生这种情况:

 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); } 

这将在使用IllegalStateException的一个测试中失败,因为模拟a在用于下一个测试之前未被重置。 要解决它,您可以执行以下操作:

 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 } 

你应该在expect电话之后, 你使用你的模拟之前把你的电话replay 。 在这种情况下,您应该将测试更改为以下内容:

 @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()); }