Настройка ожиданий издевательства в отношении защищенных методов

Я столкнулся с проблемой при попытке настроить Mockery для проверки на вызов метода. Я видел, как тестировать защищенные методы абстрактного класса, используя JUnit и JMock, и это по сути один и тот же вопрос, но я не могу понять, на что ссылается Крис в своем ответе. Если бы я мог, пожалуйста, попросите кого-нибудь объяснить мне это немного по-другому или с более полным английским языком. Я использую JUnit, JMock2, Infinitest (если это имеет значение) и стандартную систему сообщений на основе событий следующим образом:

public Interface MyEventListener {
    void handleMyEvent(MyEvent e);
}

public Class MyEvent extends EventObject {
    public MyEvent(Object source) {
        super(source);
    }
}

public Class MySource {
    protected List<MyEventListener> listeners = new ArrayList<MyEventListeners>();

    public void addListener(MyEventListener listener) {
        listeners.add(listener);
    }

    public void removeListener(MyEventListener listener) {
        listeners.remove(listener);
    }

    // other code...

    protected void raiseEvent() {
        for (MyEventListener listener : listeners) {
            listener.handleMyEvent(new MyEvent(this));
        }
    }
}

Теперь вот мой тест:

@Test
public void sourceShouldThrowEventOnEventOccurrence() {
    // set up
    Mockery context = new Mockery();
    MyEventListener listener = context.mock(MyEventListener.class);
    MySource source = new MySource();
    MyEvent event = new MyEvent(source);
    source.addListener(listener);

    // set expectations
    context.checking(new Expectations() {{
        oneOf(listener).handleMyEvent(event);
    }});

    // execute
    // do stuff to (theoretically) raise event

    // verify
    context.assertIsSatisfied();
}

Я получаю ExpectationError (неожиданный вызов) в моем защищенном методе RaiseEvent() в MySource. Как я могу добавить к ожиданию, что он должен вызывать защищенный метод?

Кроме того, мне пришла в голову мысль, но я все еще публикую это сообщение, прежде чем приступить к его изучению (в случае, если у кого-то еще возникнет тот же вопрос и моя мысль окажется правильной или нет). Может ли ошибка быть связана с тем, что в моем коде есть два новых ключевых слова? У меня есть новый MyEvent(this) в MySource.raiseEvent(), а затем у меня есть новый MyEvent(source) в тесте. Это создает два разных события в памяти... Связана ли ошибка с вероятностью того, что метод получит одно событие, но получит другое?

*****РЕДАКТИРОВАТЬ

На самом деле, в частности, я получаю ExpectationError (неожиданный вызов) в строке кода, которая фактически вызывает события. (В моем коде выше listener.handleMyEvent(new MyEvent(this)); линия)

1 ответ

Решение

Оказывается, мое подозрение, что это было связано с тем, что были созданы два разных экземпляра MyEvent, было правильным. К сожалению, это означает, что название моего вопроса вводит в заблуждение. После копания я обнаружил, что мой код работал нормально, как только я изменил свои ожидания () на следующее.

@Test
public void sourceShouldThrowEventOnEventOccurrence() {
    // set up
    Mockery context = new Mockery();
    MyEventListener listener = context.mock(MyEventListener.class);
    MySource source = new MySource();
    // MyEvent event = new MyEvent(source);  <-- NO LONGER NEEDED
    source.addListener(listener);

    // set expectations
    context.checking(new Expectations() {{
        oneOf(listener).handleMyEvent(with(any(MyEvent.class)));  // <-- with any
    }});

    // execute
    // do stuff to (theoretically) raise event

    // verify
    context.assertIsSatisfied();
}
Другие вопросы по тегам