Подсчитать косвенные вызовы методов Mockito - PullRequest
7 голосов
/ 20 октября 2011

У меня проблемы с подсчетом вызовов методов в Mockito.Проблема в том, что метод, чьи вызовы я хочу посчитать, вызывается в тестовом классе косвенно другим методом.Вот код:

public class ClassForTest {
    private Integer value;

    public void doSmth() {
        prepareValue("First call");
        prepareValue("Second call");
        prepareValue("Third call");
        System.out.println(value);
    }

    protected void prepareValue(String msg) {
        System.out.println("This is message: " + msg);
        value++;
    }
}

И тестовый класс:

public class ClassForTestTest extends TestCase {
    @Test
    public void testDoSmth() {
        ClassForTest testMock = mock(ClassForTest.class);
        doNothing().when(testMock).prepareValue(anyString());
        testMock.doSmth();
        verify(testMock, times(3)).prepareValue(anyString());
    }
}

Имея такое исключение:

Wanted but not invoked:
classForTest.prepareValue(<any>);
-> at org.testing.ClassForTestTest.testDoSmth(ClassForTestTest.java:24)

However, there were other interactions with this mock:
-> at org.testing.ClassForTestTest.testDoSmth(ClassForTestTest.java:21)

Любые идеи, пожалуйста.Заранее спасибо!

Ответы [ 4 ]

10 голосов
/ 20 октября 2011

Это будет работать.Использование spy вызывает базовый метод.Убедитесь, что value инициализирован первым.

    @Test
    public void testDoSmth() {
        ClassForTest testMock = spy(new ClassForTest());
        testMock.doSmth();
        verify(testMock, times(3)).prepareValue(anyString());
    }

    public class ClassForTest {
        private Integer value = 0;

        public void doSmth() {
            prepareValue("First call");
            prepareValue("Second call");
            prepareValue("Third call");
            System.out.println(value);
        }

        protected void prepareValue(String msg) {
            System.out.println("This is message: " + msg);
            value++;
        }
    }
5 голосов
/ 20 октября 2011

Это признак того, что вам нужен рефакторинг для улучшения вашего дизайна.Один класс должен быть полностью тестируемым без необходимости его макетирования.Любые части, которые вы считаете нужными макетировать, должны быть извлечены в один или несколько взаимодействующих объектов. Не попадите в ловушку частичных издевательств.Послушайте, что вам говорят тесты.Ваша будущая личность поблагодарит вас.

1 голос
/ 20 октября 2011

В качестве альтернативы, если вы хотите выполнить рефакторинг для тестирования, вы можете сделать следующее:

@Test
public void testDoSmth() {
    Preparer preparer = mock(Preparer.class);
    ClassForTest cft = new ClassForTest(preparer);
    cft.doSmth();
    verify(preparer, times(3)).prepareValue(anyString());
}

public class ClassForTest {
    private final Preparer preparer;

    public ClassForTest(Preparer preparer) {
        this.preparer = preparer;
    }

    public void doSmth() {
        preparer.prepareValue("First call");
        preparer.prepareValue("Second call");
        preparer.prepareValue("Third call");
        System.out.println(preparer.getValue());
    }
}

public class Preparer {
    private Integer value = 0;

    public void prepareValue(String msg) {
        System.out.println("This is message: " + msg);
        value++;
    }

    public Integer getValue() {
        return value;
    }
}
1 голос
/ 20 октября 2011

Вы издеваетесь над проверенным классом.Пересмешка предназначена для зависимостей тестируемого класса, а не самого класса.

Я подозреваю, что вы хотите Mockito.spy().Тем не менее, это частичная насмешка , против которой рекомендует Mockito Javadoc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...