Тестирование кода, который вызывает нативные методы - PullRequest
10 голосов
/ 07 февраля 2011

У меня есть такой класс:

public final class Foo
{
    public native int getBar();

    public String toString()
    {
        return "Bar: " + getBar();
    }
}

Обратите внимание, что getBar () реализован с использованием JNI и что класс final .Я хочу написать тест junit для проверки метода toString () .Для этого мне нужно смоделировать метод getBar () и затем запустить оригинальный метод toString () , чтобы проверить вывод.

Сначала я подумал, чтобыло невозможно, но потом я обнаружил PowerMock , который поддерживает тестирование финальных классов и собственных методов в соответствии со списком возможностей.Но до сих пор у меня не было успеха с этим.Лучшее, что мне удалось, - это смоделировать весь класс, но затем тест протестировал смоделированный метод toString () вместо реального, который не имеет большого смысла.использовать PowerMock для проверки этого toString () метод сверху?Я предпочитаю использовать PowerMock с Mockito , но если это невозможно, у меня нет проблем с использованием EasyMock .

Ответы [ 3 ]

8 голосов
/ 07 февраля 2011

Нашел это.То, как я это делал, было правильным.Единственное, что я пропустил, это сказал фиктивному объекту вызвать оригинальный метод при вызове toString ().Так это работает так:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Foo.class })
public class FooTest
{
    @Test
    public void testToString() throws Exception
    {
        Foo foo = mock(Foo.class);
        when(foo.getBar()).thenReturn(42);
        when(foo.toString()).thenCallRealMethod();
        assertEquals("Bar: 42", foo.toString());
    }
}
3 голосов
/ 11 февраля 2011

Или используйте JMockit с динамическое частичное моделирование :

import org.junit.*;
import mockit.*;

public class FooTest
{
    @Test
    public void testToString()
    {
        final Foo foo = new Foo();
        new Expectations(foo) {{ foo.getBar(); result = 42; }};

        assertEquals("Bar: 42", foo.toString());
    }
}
1 голос
/ 07 февраля 2011

Или используйте Шаблон стратегии :

    public final class Foo
    {
        public IBarStrategy barStrategy;

        ......
    }

    interface IBarStrategy{
        int getBar();
    }

Когда в модульном тесте внедряется фиктивный IBarStrategy экземпляр, вы можете проверить класс Foo.

...