Насмешка над объектом, который использует jni с помощью EasyMock - PullRequest
0 голосов
/ 23 декабря 2010

Таким образом, в моем тестируемом классе есть код, который выглядит бодро, как этот

public void doSomething(int param)
{
    Report report = new Report()
    ...do some calculations
    report.someMethod(someData)
}

Я намеревался извлечь конструкцию отчета в защищенный метод и переопределить его, чтобы использовать фиктивный объект, который я затем смог протестироватьчтобы убедиться, что someMethod был вызван с правильными данными.

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

Если я делаю Report report = EasyMock.createMock (Report.class)

, то EasyMockпытается использовать рефлексию, чтобы выяснить членов класса, но это вызывает попытку загрузки библиотеки JNI, которая завершается неудачей (библиотеки JNI доступны только в UNIX).

Я рассматриваю две вещи: a) ПредставьтеИнтерфейс ReportWrapper с двумя реализациями, одна из которых будет делегировать вызовы реального отчета (таким образом, в основном, Proxy), а вторая, в основном, будет использовать фиктивный объект.или б) вместо вызова someMethod вызовите защищенный метод, который, в свою очередь, вызовет someMethod, который я могу переопределить в подклассе тестирования.

В любом случае это кажется неприятным.Есть ли лучшие способы?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2011

С EasyMock вам придется прибегнуть к какой-либо форме рефакторинга. Единственный способ избежать этого - использовать инструмент-насмешник, который может создавать внутренние объекты. С помощью JMockit (инструмента, который я разрабатываю) тест можно написать так:

public void testDoSomething(final Report mockedReport)
{
    // create "someData"

    objectUnderTest.doSomething(123);

    new Verifications() {{ mockedReport.someMethod(someData); }};
}
0 голосов
/ 24 декабря 2010

Если нет интерфейса с классом Report, то предлагаемая оболочка является правильным подходом.
Книга "Рефакторинг: улучшение дизайна существующего кода" содержит главу о извлечении интерфейсов изплохо спроектированные классы.

Если вы используете какую-то DI-инфраструктуру (например, SpringFramework), вы можете легко заменить этот объект на ObjectFactory, чтобы создать правильную реализацию (макет против реальной).

...