Подчеркните, что во время модульного теста была предпринята попытка вызова метода, но на самом деле не вызывайте его - PullRequest
4 голосов
/ 03 февраля 2012

Я пишу тест JUnit, а также использую Mockito, и я хочу вызвать метод, который, в свою очередь, вызывает второй метод несколько раз.Я не хочу, чтобы этот второй метод вызывался во время моего модульного теста, но я хочу знать, каковы были бы его аргументы.Мой тестируемый код выглядит примерно так:

public class MyClass {
    public void myMethod() {
        int a = [do some logic]
        int b = [do some logic];
        doSomething(a, b);

        a = [do some logic];
        b = [do some logic];
        doSomething(a, b);
    }

    public void doSomething(int a, int b) {
        // code that I do not want to be executed during a unit test
    }
}

А теперь юнит-тест:

@Test
public void test() {
    MyClass myClass = new MyClass();
    myClass.myMethod();
    verify(myClass).doSomething(17, 33);
    verify(myClass).doSomething(9, 18);
}

Я новичок в Mockito и не знаю, возможно ли либоA) предотвратить выполнение doSomething () и B) проверить значения аргументов a & b.Я готов принять ответы типа «Мокито не может вам здесь помочь» или «это не то, что технически возможно».Если нет способа издеваться над подобными вещами, я мог бы рассмотреть возможность реорганизации этих блоков [сделать некоторую логику] в методы, которые я могу тестировать напрямую, но мой код более сложный, чем в этом простом примере, и мне не разрешается публиковать код в Интернете.

Ответы [ 2 ]

5 голосов
/ 03 февраля 2012

Шпионы безобразны.Если вы частично издеваетесь над тестируемым классом, вы легко запутаетесь в том, что проверяется и что действительно проверяется.Javadoc от Mockito недвусмысленно предупреждает о частичной имитации.

Лучше реорганизовать свой код, чтобы вы могли его аккуратно протестировать.Извлечь doSomething() в новый класс:

public class SomethingDoer {
    public void doSomething(int a, int b) {
        // code that you do not want to be executed during a unit test
    }
}

Изменен MyClass:

public class MyClass {
    private final SomethingDoer somethingDoer;

    public MyClass(SomethingDoer somethingDoer) {
        this.somethingDoer = somethingDoer;
    }

    public void myMethod() {
        int a = [do some logic]
        int b = [do some logic];
        somethingDoer.doSomething(a, b);

        a = [do some logic];
        b = [do some logic];
        somethingDoer.doSomething(a, b);
    }
}

Тест:

@Test
public void test() {
    SomethingDoer somethingDoer = mock(SomethingDoer.class);
    MyClass myClass = new MyClass(somethingDoer);
    myClass.myMethod();
    verify(somethingDoer).doSomething(17, 33);
    verify(somethingDoer).doSomething(9, 18);
}
5 голосов
/ 03 февраля 2012

Для этого вам понадобится частичный макет Mockito .

Это не проверено, но я думаю, что вы хотите что-то вроде:

@Test
public void test() {
    MyClass myClass = spy(new MyClass());
    doNothing().when(myClass).doSomething(any(Integer.class), any(Integer.class));
    myClass.myMethod();
    verify(myClass).doSomething(17, 33);
    verify(myClass).doSomething(9, 18);
}

spy устанавливает частичную имитацию, так что вы можете заменить некоторые методы и использовать некоторые реальные методы. doNothing заглушает ваш doSomething (интересное совпадение имен), чтобы ничего не делать вместо вызова реального кода.

...