Подтвердить что ты не робот

Java.lang.IllegalStateException: определение отсутствующего поведения для предыдущего вызова метода getMessage ( "title" )

Я использую EasyMock (версия 2.4) и TestNG для написания UnitTest.

У меня есть следующий сценарий, и я не могу изменить способ определения иерархии классов.

Я тестирую ClassB, который расширяет ClassA.

КлассB выглядит так

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

Когда я запускаю этот тест, я получаю следующее исключение:

java.lang.IllegalStateException: определение отсутствующего поведения для предыдущего вызова метода getMessage ( "title" )

При отладке того, что я нашел, это не относится к способу вызова метода mockMessageResourse.getMessage( "ClassB.title" ), поскольку он был вызван из конструктора (создание объекта ClassB).

Может ли кто-нибудь помочь мне в этом случае проверить.

Спасибо.

4b9b3361

Ответ 1

Вам нужно позвонить EasyMock.replay(mock) перед вызовом тестируемого метода. После вызова тестируемого метода вы можете вызвать EasyMock.verify(mock), чтобы проверить, что mock вызывается.

Затем вам нужно добавить другой вызов expect с аргументом "title", поскольку вы вызываете его дважды.

код:

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

Ответ 3

Это может иметь различные причины (someMock - это имя вашего издевающегося объекта в этом ответе). С одной стороны, может случиться так, что вам нужно ожидать вызова через

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

как в Reda answer. Также может быть, что вы забыли называть replay(someMock), прежде чем использовать макет, как вы можете видеть в сообщении Julien Rentrop.

Последнее, что возможно, что здесь не упоминалось, заключается в том, что вы использовали макет где-то еще раньше в тесте и забыли reset mock через reset(someMock).

Это может произойти, если у вас есть несколько тестов Unit, таких как:

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 не был reset перед тем, как его использовать в следующем тесте. Чтобы решить эту проблему, вы можете сделать следующее:

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
}