验证 BiConsumer 作为单元测试中的方法引用



我有一些与此非常相似的逻辑,其中我有单位和可以在请求期间更新的不同字段。

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 或其他东西编写这样的测试?

没有办法(在当前的Java实现中)比较两个lambda和/或方法引用。有关更多详细信息,请阅读这篇文章。

您可以做的(如果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时,此方法才有效。

相关内容

  • 没有找到相关文章

最新更新