Mockito проверить вызов метода внутри void метода - PullRequest
2 голосов
/ 17 октября 2019

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

public class MyClass{
    private MyObject svc;
    private MyObject2 svc2;

    public MyClass(MyObject svc){
        this.svc = svc;
        this.svc2 = new MyObject2(svc);
    }


    public void getSvc(){
        Result response = this.svc.getResponse();
        if(!response.isEmpty())
             this.svc2.filterResponse(response);
        else
            System.out.println("empty");
    }

}

Но я борюсь с тем, чтобы быть пустым методом. Как я могу проверить, что filterResponse будет вызываться только тогда, когда мой ответ не пуст?

Ответы [ 3 ]

2 голосов
/ 17 октября 2019

Это проблема проектирования, так как испытуемый не честен относительно того, что ему действительно нужно для выполнения своей заданной функции. Он тесно связывает себя через new MyObject2(...) таким образом, что затрудняет (не делает невозможным) тестирование в изоляции.

Тот факт, что MyObject2 зависит от MyObject, является деталью реализации, которая MyClassне нужно знать.

Следуя явному принципу зависимости,

Методы и классы должны явно требовать (обычно через параметры метода или параметры конструктора) любых взаимодействующих объектов, в которых они нуждаются для функционированияправильно.

MyClass должен быть соответственно изменен рефакторинг

public class MyClass{
    private MyObject svc;
    private MyObject2 svc2;

    public MyClass(MyObject svc, MyObject2 svc2){
        this.svc = svc;
        this.svc2 = svc2;
        //this.svc2 = new MyObject2(svc); // <-- remove implementation details
    }

    public void getSvc(){
        Result response = this.svc.getResponse();
        if(!response.isEmpty())
             this.svc2.filterResponse(response);
        else
            System.out.println("empty");
    }
}

Разрешение на то, чтобы необходимые тесты / заглушки были явно введены в испытуемый объект при тестировании в изоляции.

//Arrange
MyObject svc = mock(MyObject.class);
MyObject2 svc2 = mock(MyObject2.class);

MyClass subject = new MyClass(svc, svc2);

Result response = mock(Result.class);
when(response.isEmpty()).thenReturn(false);

when(svc.getResponse()).thenReturn(response);

//Act
subject.getSvc();

//Assert
verify(svc2, times(1)).filterResponse(response); //verify method call inside void method

И тот факт, что тестируемый метод является void, не является следствием проверяемого поведения.

0 голосов
/ 17 октября 2019

Вы должны автоматически подключить или внедритьMock вашего myClass, так как он должен создать бин, чтобы при вызове getSvc () он удовлетворял вашему условию

0 голосов
/ 17 октября 2019

Если этот дизайн предназначен, и вы не можете изменить существующий код. Вот подход, который вы можете сделать:

  1. Внутри вашего класса Test. Объявите новый статический внутренний класс (например, InternalMyClass), который расширяет ваш MyClass
  2. Добавление нового конструктора для вашего внутреннего класса с 2 параметрами.
  3. Теперь внутри вашего тестового примера создайте свой MyClass со своим внутренним классом. Вы можете передать свой шпион / заглушку для MyObject2 сейчас.
...