EasyMock: Void Методы - PullRequest
       22

EasyMock: Void Методы

67 голосов
/ 13 мая 2009

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

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

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

Ответы [ 5 ]

90 голосов
/ 13 мая 2009

Если я понимаю, что вы хотите сделать правильно, вы сможете использовать 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;
    }
});

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

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

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

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

22 голосов
/ 13 мая 2009

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

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

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

«Fun With EasyMock» от другого пользователя StackOverflow Burt Beckwith - хороший пост в блоге, в котором содержится более подробная информация Известная выдержка:

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

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

Если вам нужен только доступ к параметрам на более поздний срок, вы также можете оценить класс Captures , который является новым для 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());
1 голос
/ 31 мая 2013

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

В PowerMock API инструментария Java 5 снимает ограничения. Не нужно писать фиктивные реализации объекта тестируемого объекта (просто уродливый ИМО). Соедините PowerMock с Mockito (или JMockit), и вы действительно отправитесь в гонки.

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

0 голосов
/ 13 мая 2009

В подобных ситуациях я обнаружил, что создание вложенного класса в моем классе модульного теста и переопределение методов с особыми требованиями таким образом - лучший путь. Так что если вы тестируете 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
    }
}

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

...