简体   繁体   English

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

[英]java.lang.IllegalStateException: missing behavior definition for the preceding method call getMessage(“title”)

I'm using EasyMock(version 2.4) and TestNG for writing UnitTest.我正在使用 EasyMock(2.4 版)和 TestNG 来编写 UnitTest。

I have a following scenario and I cannot change the way class hierarchy is defined.我有以下场景,我无法更改定义类层次结构的方式。

I'm testing ClassB which is extending ClassA.我正在测试扩展 ClassA 的 ClassB。

ClassB look like this B类看起来像这样

public class ClassB extends ClassA  {

  public ClassB()
    {
        super("title");
    }

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

}

ClassA code A类代码

public abstract class ClassA {
    private String title;

    public ClassA(String title)
    {
        this.title = ClientMessages.getMessages(title);
    }

    public String getDisplayName()
    {
        return this.title;
    }
}

ClientMessages class code 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 Class code消息资源类代码

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

Testing ClassB测试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);
    }
}

When I'm running this this test I'm getting following exception:当我运行此测试时,出现以下异常:

java.lang.IllegalStateException: missing behavior definition for the preceding method call getMessage("title") java.lang.IllegalStateException:缺少前面方法调用 getMessage("title") 的行为定义

While debugging what I found is, it's not considering the mock method call mockMessageResourse.getMessage("ClassB.title") as it has been called from the construtor (ClassB object creation).在调试我发现的是,它没有考虑模拟方法调用mockMessageResourse.getMessage("ClassB.title")因为它是从构造函数调用的(ClassB 对象创建)。

Can any one please help me how to test in this case.任何人都可以帮助我如何在这种情况下进行测试。

Thanks.谢谢。

You need to call EasyMock.replay(mock) before calling the method under test.您需要在调用被测方法之前调用EasyMock.replay(mock) After calling the method under test you can call EasyMock.verify(mock) to verify the mock is called.在调用被测方法后,您可以调用EasyMock.verify(mock)来验证模拟是否被调用。

Next you need to add another expect call with the "title" argument since you call it twice.接下来您需要添加另一个带有“title”参数的expect调用,因为您调用了它两次。

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

In my case, it was caused by the omission of a return value specification (andReturn(...)).就我而言,这是由于省略了返回值规范(andReturn(...))造成的。 http://www.smcmaster.com/2011/04/easymock-issue-1-missing-behavior.html for more details. http://www.smcmaster.com/2011/04/easymock-issue-1-missing-behavior.html了解更多详情。

This can have various causes ( someMock is the name of your mocked Object in this answer).这可能有多种原因( someMock是此答案中someMock对象的名称)。 On the one side it can be that you need to expect the call via一方面,您可能需要通过以下方式期待呼叫

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

like in Reda's answer .就像在Reda 的回答中一样 It can also be that you forgot to call replay(someMock) before you used the mock, like you can see in Julien Rentrop's answer .也可能是您在使用模拟之前忘记调用replay(someMock) ,就像您在Julien Rentrop's answer 中看到的那样。

A last thing that is possible that wasn't mentioned here is that you used the mock somewhere else before in a test and forgot to reset the mock via reset(someMock) .这里没有提到的最后一件事是,您之前在测试中在其他地方使用了模拟,而忘记通过reset(someMock)重置模拟。

This can happen if you have multiple Unit Tests like this:如果您有多个这样的单元测试,就会发生这种情况:

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

This will fail on one test with the IllegalStateException, because the mock a was not reset before being used in the next test.这将在带有 IllegalStateException 的一个测试中失败,因为在下一个测试中使用模拟 a 之前没有重置。 To solve it you can do the following:要解决它,您可以执行以下操作:

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
}

You should put your call to replay after the expect calls, and before you use your mock.您应该在expect调用之后和使用模拟之前将调用置于replay In this case you should change your test to something like this:在这种情况下,您应该将测试更改为如下所示:

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

For me, this exception was occurring because the method I was trying to stub was final (something I hadn't realized).对我来说,发生这个异常是因为我试图存根的方法是final (我没有意识到这一点)。

If you want to stub a final method you'll need to use Powermock .如果要存根final方法,则需要使用Powermock

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.IllegalStateException:前面的方法调用getLast(...)的行为定义缺失 - java.lang.IllegalStateException: missing behavior definition for the preceding method call getLast(…) java.lang.IllegalStateException:没有对静态方法可用的模拟的最后一次调用 - java.lang.IllegalStateException: no last call on a mock available for static method IllegalStateException:在同一方法中有两次调用时缺少行为定义 - IllegalStateException: missing behavior definition when having a double call in same method 呼叫记录失败,并出现java.lang.IllegalStateException - Call Recording failed with java.lang.IllegalStateException java.lang.IllegalStateException:找不到方法? - java.lang.IllegalStateException: Could not find a method? 方法中带有@Async的java.lang.IllegalStateException - java.lang.IllegalStateException with @Async in method java.lang.IllegalStateException:找不到方法 - java.lang.IllegalStateException: Could not find method java.lang.IllegalStateException - java.lang.IllegalStateException java.lang.IllegalStateException:没有在bean定义上指定bean类 - java.lang.IllegalStateException: No bean class specified on bean definition java.lang.IllegalStateException:在堆栈上找不到调用#0。 记录方法调用无效? - java.lang.IllegalStateException: can not found call #0 on stack. Invalid call of record method?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM