2012-02-03 40 views
4

私はJUnitテストを書いており、Mockitoも使用しています。メソッドを呼び出すと、回。単体テスト中に2番目のメソッドを呼び出すことは望ましくありませんが、私はそれがどのようなものだったのかを知りたいと思います。単体テスト中にメソッド呼び出しが試行されたが、実際には呼び出していないが、実際には呼び出さない

public class MyClass { 
    public void myMethod() { 
     int a = [do some logic] 
     int b = [do some logic]; 
     doSomething(a, b); 

     a = [do some logic]; 
     b = [do some logic]; 
     doSomething(a, b); 
    } 

    public void doSomething(int a, int b) { 
     // code that I do not want to be executed during a unit test 
    } 
} 

そして今、ユニットテスト:

@Test 
public void test() { 
    MyClass myClass = new MyClass(); 
    myClass.myMethod(); 
    verify(myClass).doSomething(17, 33); 
    verify(myClass).doSomething(9, 18); 
} 

私はMockitoに新しいですし、どちらかA)doSomethingのを防止することができるかどうかはわからないテストするために私のコードは次のようになります()を実行し、B)& b引数の値を確認する。私は "Mockitoはあなたをここで助けることができない"または "これは技術的に可能なものではない"のような答えを受け入れることを望んでいます。このような事態を模倣する方法がない場合、私はそれらのロジックブロックを直接テストできる方法にリファクタリングすることを検討するかもしれませんが、私のコードはこの単純な例よりも複雑であり、コードをオンラインで投稿することはできません。

+0

をあなたは便利なこの質問への答えを見つけることがあります。 ます。http:// stackoverflowの。 com/questions/1087339/using-mockito-to-test-abstract-classes – tjdett

答えて

5

スパイは醜いです。テスト中のクラスを部分的にモックすると、嘲笑されたものと実際にテストされたものについて混乱することは簡単です。 MockitoのJavadocは部分的な嘲笑に対して明示的に警告します。

コードをリファクタリングして、きれいにテストできるようにしてください。新しいクラスにdoSomething()を抽出します。

MyClassの変更
public class SomethingDoer { 
    public void doSomething(int a, int b) { 
     // code that you do not want to be executed during a unit test 
    } 
} 

public class MyClass { 
    private final SomethingDoer somethingDoer; 

    public MyClass(SomethingDoer somethingDoer) { 
     this.somethingDoer = somethingDoer; 
    } 

    public void myMethod() { 
     int a = [do some logic] 
     int b = [do some logic]; 
     somethingDoer.doSomething(a, b); 

     a = [do some logic]; 
     b = [do some logic]; 
     somethingDoer.doSomething(a, b); 
    } 
} 

テスト:

@Test 
public void test() { 
    SomethingDoer somethingDoer = mock(SomethingDoer.class); 
    MyClass myClass = new MyClass(somethingDoer); 
    myClass.myMethod(); 
    verify(somethingDoer).doSomething(17, 33); 
    verify(somethingDoer).doSomething(9, 18); 
} 
+0

+1:私は部分的なモックをどうやって行うかについて、うれしく思っていましたが、それは良いアドバイスです。 –

+0

私は結局、別の理由で今日doSomething()を新しいクラスにリファクタリングする必要がありました。当然、これは私が行った解決策ですが、両方の視点を得ることは良いことでした。 –

5

これを行うには、Mockito partial mockが必要です。

これはテストされていないですが、私は何がしたいことの線に沿って何かかもしれないと思う:

@Test 
public void test() { 
    MyClass myClass = spy(new MyClass()); 
    doNothing().when(myClass).doSomething(any(Integer.class), any(Integer.class)); 
    myClass.myMethod(); 
    verify(myClass).doSomething(17, 33); 
    verify(myClass).doSomething(9, 18); 
} 

あなたには、いくつかの方法を交換し、いくつかの実際のメソッドを使用することができるようにspyは、部分的モックを設定します。 doNothingスタブあなたのdoSomething(興味深い名前の偶然の一致)は、実際のコードを呼び出す代わりに何もしません。

+0

成功!しかし、私はしばらくの間、NullPointerExceptionを取得していましたが、それを根絶しようとしている間にスパイとスタブについてたくさんのことを学びました。すべての事のうち、NPEは 'any(Integer.class) 'によって引き起こされました。それを 'Mockito.anyInt()'と置き換えてから、もう一度やり直す必要がありました。奇妙な。ありがとうございました! –

関連する問題