Christoph Grimmer
Christoph Grimmer

Reputation: 4323

How to verify a method call through a functional interface with Mockito?

I'm using a Supplier to instantiate a field thread safe while avoiding consecutive calls to the synchronized method.

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;
    }
}

When I'm running my Unit Tests I want to make sure that initFoo() is called exactly once. Sadly verify(classUnderTest, times(1)).initFoo() does not register that initFoo is entered. I debugged this and calling getFoo() does in turn enter initFoo.

Any ideas?

Upvotes: 2

Views: 3074

Answers (1)

a better oliver
a better oliver

Reputation: 26848

I assume your test code looks something like this:

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

The problem is that this.fooGetter = this::initFoo; is called before you start spying on the object. At this point this refers to the real object, not to the spy. And that reference is captured when the method reference is created. Therefore the call cannot be registered.

Upvotes: 1

Related Questions