EasyMock: Методы Void



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



этот класс огромен, и я использую только этот единственный метод из него.
Мне нужно заменить реализацию этого метода для теста, поскольку я хочу, чтобы он делал что-то другое, и мне нужно иметь доступ к параметрам, которые получает этот метод.



Я не могу найти способ сделать это в EasyMock. Я думаю, что знаю, как это сделать Mockito С помощью doAnswer но я не хочу добавлять другую библиотеку без крайней необходимости.

649   5  

5 ответов:

если я правильно понял, что вы хотите сделать правильно, вы должны быть в состоянии использовать andAnswer():

mockObject.someMethod(eq(param1), eq(param2));
expectLastCall().andAnswer(new IAnswer() {
    public Object answer() {
        //supply your mock implementation here...
        SomeClass arg1 = (SomeClass) getCurrentArguments()[0];
        AnotherClass arg2 = (AnotherClass) getCurrentArguments()[1];
        arg1.doSomething(blah);
        //return the value to be returned by the method (null for void)
        return null;
    }
});

The Руководство Пользователя EasyMock объясняю:

создание возвращаемых значений и исключений

иногда мы хотели бы, чтобы наш макет объекта возвращал значение или создавал исключение, которое создается во время фактического вызова. С EasyMock 2.2, объект, возвращенный expectLastCall() и expect(T value) обеспечивает метод andAnswer(IAnswer answer) что позволяет [вам] указать реализацию интерфейса IAnswer который используется для создания возвращаемого значения или исключения.

внутри IAnswer обратный вызов, аргументы, переданные в макет вызова доступны через EasyMock.getCurrentArguments(). Если вы используете их, рефакторинги, такие как параметры переупорядочения, могут нарушить ваши тесты. Вы были предупреждены.

если вы просто вызываете метод void для каждого раза, когда вы ожидаете его вызова, а затем вызываете EasyMock.expectLastCall() перед вызовом replay(), Easymock будет "помнить" каждый вызов.

поэтому я не думаю, что вам нужно явно вызывать expect() (кроме lastCall) так как вы ничего не ожидаете от метода void, кроме его вызова.

Спасибо, Крис!

"Весело С EasyMock" по товарищу StackOverflow user Берт Беквит это хороший пост в блоге, который предоставляет более подробную информацию. Примечательный отрывок:

в основном поток, который я обычно использую:

  1. создать макет
  2. вызов expect(mock.[method call]).andReturn([result]) для каждого ожидаемого вызова
  3. вызов mock.[method call], потом EasyMock.expectLastCall() для каждого ожидаемого пустого вызова
  4. вызов replay(mock) для переключения из режима "запись" в режим "воспроизведение"
  5. введите макет по мере необходимости
  6. вызов тест метод
  7. вызов verify(mock) чтобы убедиться, что все ожидаемые звонки произошли

Если вы хотите получить доступ только к параметрам позже, вы также можете оценить захват класс, который является новым для EasyMock 2.4.

вы можете использовать экземпляр класса "Capture" вместо сопоставителя. Когда вызывается ваш издевательский метод, экземпляр Capture сохранит параметр, с которым он был вызван.

Capture<ChartPanel> captured = new Capture<ChartPanel>();
// setChartPanel is going to be called during execution;
// we want to verify some things about the ChartPanel
// instance it's invoked with
chartMock.setChartPanel(capture(captured));
replay(chartMock);

ufdm.setChartAnnotater(chartMock);
// afterPropertiesSet triggers the setChartPanel call...
ufdm.afterPropertiesSet();
verify(chartMock);

// verify some things about the ChartPanel parameter our
// mock object was invoked with
assertSame(plot, captured.getValue().getChart().getPlot());

вы можете проверить PowerMock. EasyMock основан на API отражения прокси, что означает, что все является прокси, и вы можете тестировать только интерфейсы и, следовательно, только не окончательные методы и классы. Это может сработать для некоторых, но если вы тестируете мир как построенный, вам понадобится больше энергии.

с PowerMock API инструментария Java 5 удаляет ограничения. Нет необходимости писать макетные реализации объекта для тестирования (просто уродливый IMO). Пара PowerMock с Mockito (или JMockit), и вы действительно отправитесь на гонки.

конечно, есть и другое направление переписывания кода, которое будет легче протестировать, что, как правило, тоже хорошая идея, если это возможно.

в таких ситуациях я обнаружил, что создание вложенного класса в моем классе модульного теста и переопределение методов с особыми требованиями таким образом является лучшим маршрутом. Так что если вы тестируете ClassA который имеет этот метод с параметрами, которые вам нужно получить доступ, вы бы сделали что-то вроде:

class MockClassA extends ClassA {
    @Override
    void specialMethod(String param1, String param2) {
        // do logging or manipulation of some sort
        super.specialMethod(param1,param2); // if you need to
    }
}

в моем коде модульного тестирования я просто использую этот экземпляр вместо этого. Просто относитесь к нему так, как если бы это был любой другой макет объекта. Гораздо проще, чем смешивать библиотеки, что я согласен, вероятно не очень хорошая идея.

Comments

    Ничего не найдено.