2011-11-09 31 views
1

ArgumentMatchersを使用する次のJUnitテストを作成しました。ArgumentMatcherを使用する場合のNullPointerException

MyClass classUnderTest = new MyClass(); 

    class AnyBooleanMatcher extends ArgumentMatcher<Boolean> { 
     public boolean matches(Object argument) { 
      return ((Boolean) argument).equals(Boolean.TRUE); 
     } 
    } 

    class MyObjectMatcher extends ArgumentMatcher<MyObject> { 
     public boolean matches(Object argument) { 
      return ((MyObject) argument).getValue().equals("123"); 
     } 
    } 

    final Service mockService = mock(Service.class); 

    when(mockService.search(Matchers.argThat(new MyObjectMatcher()), 
      Matchers.argThat(new AnyBooleanMatcher()))); 

    classUnderTest.callMethod(mock(ActionEvent.class)); 

    verify(mockService).search(Matchers.argThat(new MyObjectMatcher()), 
      Matchers.argThat(new AnyBooleanMatcher())); 

残念ながら、私はいつもwhen声明で、NullPointerExceptionを取得しています。

なぜか分かります。argThatは、JavaDocで指定されているようにnullを返します。しかし、正確に同じ方法でモデル化されたexampleのテストがうまくいかない場合、私のテストがうまくいかない理由はわかりません。

+4

*正確に*はNPEですか? 'when'ステートメントには、NPEを引き起こしている埋め込みメソッド呼び出しがたくさんあります。 –

+0

NPEは 'Matchers.argThat(new MyObjectMatcher())'で発生すると思います。少なくともそこには、メソッドでこのステートメントを抽出するときも発生します(Mockitoのドキュメントで推奨されています)。そして、「argThat」は、定義帰り「null」であるべきです。 : - | –

答えて

3

メソッドシグニチャがネイティブタイプを使用していて、オブジェクトを返すMatchers.argThatを使用しているため、NullPointerExceptionがあります。

コンパイル時に、nullが返ってくるので、JavacはMatchers.argThat(new AnyBooleanMatcher())の周りに自動アンボクシングコードを追加します。そのため、NPEの原因があります。

私は確かにmockitoのJavadocはネイティブタイプを扱うときにintThat,booleanThatスタイルメソッドを使用するとも言います。それらを使用すると、コンパイラによって導入された自動アンボクシングコードが防止されます。

別のトピックでは、読みやすくするために、このようなコードを書くことをお勧めします。

when(mockService.search(argThat(hasValue("123")), booleanThat(isTrue()))).thenReturn("something"); 

// ... 

private AnyBooleanMatcher isTrue() { 
    return new AnyBooleanMatcher(); 
} 

private MyObjectMatcher hasValue(String value) { 
    return new MyObjectMatcher(value); 
} 
+0

ありがとうございます。オートボクシングによってNullPointerExceptionが発生しました。 –

+0

ありがとうございます。ネイティブタイプは私の間違いを実感させました。 –

関連する問題