【问题标题】:How to verify a method call through a functional interface with Mockito?如何通过带有 Mockito 的功能接口验证方法调用?
【发布时间】:2016-04-19 11:28:04
【问题描述】:

我正在使用 Supplier 实例化字段线程安全,同时避免连续调用同步方法。

class MyClass extends AbstractClassWithContext {

    Supplier<Foo> fooGetter;
    Foo foo;    

    public MyClass() {
        this.fooGetter = this::initFoo;
    }

    Foo getFoo(){
        return fooGetter.get();
    }

    synchonized Foo initFoo(){
        if(Objects.isNull(this.foo)) {
            this.foo = getContext().getFoo();
        }
        this.fooGetter = () -> this.foo;
        return this.foo;
    }
}

当我运行单元测试时,我想确保只调用一次 initFoo()。可悲的是 verify(classUnderTest, times(1)).initFoo() 没有注册 initFoo 被输入。我对此进行了调试,然后调用getFoo() 会依次进入initFoo。

有什么想法吗?

【问题讨论】:

    标签: java-8 mockito verify functional-interface


    【解决方案1】:

    我假设您的测试代码如下所示:

    MyClass spiedOnObject = spy(new MyClass());
    spiedOnObject.getFoo();
    verify(spiedOnObject , times(1)).initFoo();
    

    问题是this.fooGetter = this::initFoo; 在您开始监视对象之前被调用。此时this指的是真实对象,而不是间谍。并且在创建方法引用时会捕获该引用。因此无法注册通话。

    【讨论】:

    • 我将分配移至字段声明,但这不会改变结果。
    • @ChristophGrimmer-Dietrich 因为这不会改变情况。只有在spy(new MyClass()); 之后的调用才会被注册。
    • @ChristophGrimmer-Dietrich 恐怕你不能。问题是在构造时this 指向真实对象,而不是间谍。并且在创建方法引用时捕获该引用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 1970-01-01
    • 2012-02-04
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多