Проверьте BiConsumer как ссылку на метод в модульном тесте - PullRequest
0 голосов
/ 22 января 2019

У меня есть некоторая логика, очень похожая на эту, где у меня есть единица измерения и различные поля, которые можно обновлять во время запроса.

public class Unit {
    int x;
    int y;

    public void updateX(int x) {
        this.x += x;
    }

    public void updateY(int y) {
        this.y += y;
    }
}

public class UpdateUnitService{
    public Unit update(int delta, BiConsumer<Unit, Integer> updater){
        Unit unit = getUnit(); //method that can`t be mocked
        updater.accept(unit, delta);
        // some save logic

        return unit;
    }
}

public class ActionHandler{
    private UpdateUnitService service;

    public Unit update(Request request){
        if (request.someFlag()){
            return service.update(request.data, Unit::updateX);
        }else {
            return service.update(request.data, Unit::updateY);
        }
    }
}

И мне нужно написать тест для проверки, какая функция была вызвана.Примерно так.

verify(service).update(10, Unit::updateX);
verify(service).update(10, Unit::updateY);

Как написать такой тест, используя ArgumentCaptor или что-то еще?

1 Ответ

0 голосов
/ 22 января 2019

Нет способа (в текущей реализации Java) сравнить две лямбды и / или ссылки на методы.Для получения более подробной информации прочитайте этот пост .

Что вы можете сделать (в случае, если getUnit() не может быть смоделировано), это проверить, делают ли две ссылки на метод одно и то же при вызове.Но вы не можете проверить какие-либо неизвестные побочные эффекты.

public void verifyUpdateTheSameField(Integer value, BiConsumer<Unit, Integer> updater1, BiConsumer<Unit, Integer> updater2) {
    Unit unit1 = // initialize a unit
    Unit unit2 = // initialize to be equal to unit1

    actual.accept(unit1, value);
    expected.accept(unit2, value);

    assertThat(unit1).isEqualTo(unit2);
}

И затем:

ArgumentCaptor<Integer> valueCaptor = ArgumentCaptor.forClass(Integer.class);
ArgumentCaptor<BiConsumer<Unit, Integer>> updaterCaptor = ArgumentCaptor.forClass(BiConsumer.class);

verify(handler.service, times(1)).update(valueCaptor.capture(), updaterCaptor.capture());

verifyUpdateTheSameFields(valueCaptor.getValue(), updaterCaptor.getValue(), Unit::updateX);

Примечание: этот подход будет работать, только если Unit переопределяет equals.

...