2016-04-19 5 views
2

私はサプライヤを使用して、synchronizedメソッドへの連続呼び出しを避けながらフィールドスレッドをインスタンス化しています。Mockitoとの機能インタフェースを介してメソッド呼び出しを確認する方法は?

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を入力します。

アイデア?

答えて

1

私はあなたのテストコードは次のようになりますと仮定します。

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

問題は、あなたがオブジェクトをスパイを開始する前this.fooGetter = this::initFoo;が呼び出されるということです。この時点でthisはスパイではなく、実際のオブジェクトを参照します。その参照は、メソッド参照が作成されるときにキャプチャされます。したがって、通話を登録することはできません。

+0

フィールド宣言に割り当てを移しましたが、結果は変わりません。 –

+1

@ ChristophGrimmer-Dietrichそれは状況を変えないからです。 'spy(new MyClass());の後の呼び出しのみが登録されます。 – zeroflagL

+0

情報ありがとうございます。さて....私はこれをどのように修正するのですか? :-D –

関連する問題