Reputation: 4323
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
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