EasyMock: Методы Void

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

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

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

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 Руководство Пользователя объясняю:

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

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

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


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

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

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

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

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

  1. создать макет
  2. вызов expect(mock.[method call]).andReturn([result]) для каждого ожидаемого вызова
  3. вызов mock.[method call], потом EasyMock.expectLastCall() для каждого ожидаемого вызова void
  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 с Мокито (или 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
    }
}

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