Вопрос

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

«Весело с EasyMock» от другого пользователя StackOverflow Берт Беквит это хорошая запись в блоге, в которой содержится более подробная информация.Примечательный отрывок:

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top