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