java.lang.IllegalStateException:前面的方法调用getMessage(“title”)缺少行为定义
我正在使用EasyMock(版本2.4)和TestNG编写UnitTest 我有以下一个场景,我无法更改类层次结构的定义方式 我正在测试ClassB,它扩展了ClassA ClassB看起来像这样java.lang.IllegalStateException:前面的方法调用getMessage(“title”)缺少行为定义,java,unit-testing,testng,easymock,Java,Unit Testing,Testng,Easymock,我正在使用EasyMock(版本2.4)和TestNG编写UnitTest 我有以下一个场景,我无法更改类层次结构的定义方式 我正在测试ClassB,它扩展了ClassA ClassB看起来像这样 public class ClassB extends ClassA { public ClassB() { super("title"); } @Override public String getDisplayName() {
public class ClassB extends ClassA {
public ClassB()
{
super("title");
}
@Override
public String getDisplayName()
{
return ClientMessages.getMessages("ClassB.title");
}
}
A类代码
public abstract class ClassA {
private String title;
public ClassA(String title)
{
this.title = ClientMessages.getMessages(title);
}
public String getDisplayName()
{
return this.title;
}
}
public class ClientMessages {
private static MessageResourse messageResourse;
public ClientMessages(MessageResourse messageResourse)
{
this.messageResourse = messageResourse;
}
public static String getMessages(String code)
{
return messageResourse.getMessage(code);
}
}
public class MessageResourse {
public String getMessage(String code)
{
return code;
}
}
客户端消息类代码
public abstract class ClassA {
private String title;
public ClassA(String title)
{
this.title = ClientMessages.getMessages(title);
}
public String getDisplayName()
{
return this.title;
}
}
public class ClientMessages {
private static MessageResourse messageResourse;
public ClientMessages(MessageResourse messageResourse)
{
this.messageResourse = messageResourse;
}
public static String getMessages(String code)
{
return messageResourse.getMessage(code);
}
}
public class MessageResourse {
public String getMessage(String code)
{
return code;
}
}
消息资源类代码
public abstract class ClassA {
private String title;
public ClassA(String title)
{
this.title = ClientMessages.getMessages(title);
}
public String getDisplayName()
{
return this.title;
}
}
public class ClientMessages {
private static MessageResourse messageResourse;
public ClientMessages(MessageResourse messageResourse)
{
this.messageResourse = messageResourse;
}
public static String getMessages(String code)
{
return messageResourse.getMessage(code);
}
}
public class MessageResourse {
public String getMessage(String code)
{
return code;
}
}
测试类别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);
}
}
当我运行此测试时,会出现以下异常:
java.lang.IllegalStateException:前面的方法调用getMessage(“title”)缺少行为定义
在调试时,我发现它没有考虑mock方法调用
mockMessageResources.getMessage(“ClassB.title”)它是从构造函数(ClassB对象创建)调用的
有谁能帮我在这种情况下如何测试吗
谢谢。在调用测试中的方法之前,您需要调用
EasyMock.replay(mock)
。调用测试中的方法后,可以调用EasyMock.verify(mock)
来验证是否调用了mock
接下来,您需要添加另一个带有“title”参数的expect
调用,因为您调用了它两次
代码:
在我的例子中,这是由于省略了返回值规范(andReturn(…)造成的。
有关更多详细信息。这可能有多种原因(
someMock
是此答案中模拟对象的名称)。
一方面,你可能需要通过
expect(someMock.someMethod(anyObject()).andReturn("some-object");
比如说。
也可能是您在使用模拟之前忘记调用replay(someMock)
,如中所示
这里没有提到的最后一件事是,您以前在测试中在其他地方使用了模拟,但忘记了通过reset(someMock)
重置模拟
如果您有以下多个单元测试,则可能会发生这种情况:
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);
}
@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());
}
这将在带有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
。在这种情况下,您应该将测试更改为以下内容:
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);
}
@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());
}
对我来说,发生这种异常是因为我尝试存根的方法是
final
(我没有意识到)
如果你想存根一个
final
方法,你需要使用。这里也一样。检查方法是否在您不期望的情况下返回某些内容(方法链接)似乎是个好主意。缺少reset()
是我的问题。