Mockito с @Mock и @InjectMock Требуется, но не вызывается: на самом деле, с этим макетом не было никаких взаимодействий - PullRequest
1 голос
/ 12 марта 2020

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

   public class DivisionCalculator {
    private final Validator validator;
    private final MathProvider mathProvider;
    private final ViewProvider viewProvider;

    public DivisionCalculator(Validator validator, MathProvider mathProvider, ViewProvider viewProvider) {
        this.validator = validator;
        this.mathProvider = mathProvider;
        this.viewProvider = viewProvider;
    }

    public String calculate(int dividend, int divisor) {
        validator.validate(dividend, divisor);

        List<DivisionStep> items = mathProvider.calculate(dividend, divisor);

        DivisionResult result = DivisionResult.builder()
                .dividend(dividend)
                .divisor(divisor)
                .finalResult(mathProvider.finalResult(items))
                .items(items)
                .build();

        return viewProvider.provideView(result);
    }
}

У меня есть следующий тестовый класс, который отлично работает и проходит тест, используя Mockito.mock (dependency.class)

    public class DivisionCalculatorTest {

    private ViewProvider viewProvider = Mockito.mock(ViewProvider.class);
    private MathProvider mathProvider = Mockito.mock(MathProvider.class);
    private Validator validator = Mockito.mock(Validator.class);

    private DivisionCalculator divisionCalculator = new DivisionCalculator(validator, mathProvider, viewProvider);

    DivisionResult makeDivision(int dividend, int divisor) {
        List<DivisionStep> items = mathProvider.calculate(dividend, divisor);
        return DivisionResult.builder()
                .dividend(dividend)
                .divisor(divisor)
                .finalResult(mathProvider.finalResult(items))
                .items(items)
                .build();
    }

    @Test
    void divisionCalculatorShouldSuccessfullyCallHisComponents() {

        divisionCalculator.calculate(4, 2);

        Mockito.verify(validator).validate(Mockito.anyInt(), Mockito.anyInt());
        Mockito.verify(mathProvider).calculate(Mockito.anyInt(),Mockito.anyInt());
        Mockito.verify(viewProvider).provideView(refEq(makeDivision(4, 2)));

    }
}

Но чтобы следовать рекомендациям по работе с макетами, я хочу заменить Mockito.mock (dependency.class) на @ Mock и @ InjectMock аннотации

public class DivisionTest {
    @Mock
    private Validator validator = new Validator();
    @Mock
    private ViewProvider viewProvider = new ViewProvider();
    @Mock
    private MathProvider mathProvider = new MathProvider();

    @BeforeEach
    void setup() {
        MockitoAnnotations.initMocks(this);
    }
    @InjectMocks
    private DivisionCalculator divisionCalculator = new DivisionCalculator(validator, mathProvider, viewProvider);

    DivisionResult makeDivision(int dividend, int divisor) {
        List<DivisionStep> items = mathProvider.calculate(dividend, divisor);
        return DivisionResult.builder()
                .dividend(dividend)
                .divisor(divisor)
                .finalResult(mathProvider.finalResult(items))
                .items(items)
                .build();
    }

    @Test
    void divisionCalculatorShouldSuccessfullyCallHisComponents() {

        divisionCalculator.calculate(4, 2);

        Mockito.verify(validator).validate(4, 2);
        Mockito.verify(mathProvider).calculate(4, 2);
        Mockito.verify(viewProvider).provideView(refEq(makeDivision(4, 2)));
    }
}

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

1 Ответ

3 голосов
/ 12 марта 2020

Если у вас есть аннотации, такие как @Mock и @InjectMocks, вам нужно запустить тест Junit со специальным расширением в Junit 5:

@ExtendWith(MockitoExtension.class)
class MyTest {
    @Mock
    private Validator validator;
     ...
}

Также обратите внимание, что это расширение создает насмешки для вас и внедряет значения в аннотированных полях данных. Технически неправильно создавать реальные объекты, как показано в вопросе:

public class DivisionTest {
    @Mock
    private Validator validator = new Validator();  // this is wrong, don't use "new"
    @Mock
    private ViewProvider viewProvider = new ViewProvider(); // this is wrong, don't use "new"
    @Mock
    private MathProvider mathProvider = new MathProvider(); // this is wrong, don't use "new"

Вы можете следовать этому учебному пособию для более подробного примера и объяснений.

Для полноты картины, если вы используете Junit 4, вы можете использовать:

@RunWith(MockitoJUnitRunner.class)
public class DivisionTest {...}
...