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

后端 未结 5 1790
礼貌的吻别
礼貌的吻别 2021-02-06 22:54

I\'m using EasyMock(version 2.4) and TestNG for writing UnitTest.

I have a following scenario and I cannot change the way class hierarchy is defined.

I\'m testin

相关标签:
5条回答
  • 2021-02-06 23:31

    This can have various causes (someMock is the name of your mocked Object in this answer). 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. 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.

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

    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. 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
    }
    
    0 讨论(0)
  • 2021-02-06 23:40

    For me, this exception was occurring because the method I was trying to stub was final (something I hadn't realized).

    If you want to stub a final method you'll need to use Powermock.

    0 讨论(0)
  • 2021-02-06 23:43

    You should put your call to replay after the expect calls, and before you use your mock. 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());
    }
    
    0 讨论(0)
  • 2021-02-06 23:49

    In my case, it was caused by the omission of a return value specification (andReturn(...)). http://www.smcmaster.com/2011/04/easymock-issue-1-missing-behavior.html for more details.

    0 讨论(0)
  • 2021-02-06 23:55

    You need to call EasyMock.replay(mock) before calling the method under test. After calling the method under test you can call EasyMock.verify(mock) to verify the mock is called.

    Next you need to add another expect call with the "title" argument since you call it twice.

    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);
    
    0 讨论(0)
提交回复
热议问题