2013-07-30 68 views
5

私のクラスの1つでCollections.shuffle()メソッドが呼び出されたことを確認しようとしています。私はPowerMockのMockitoに関する(少しの)ドキュメントを読んで、この問題を扱った他のSOの質問を読んだが、解決は得られなかった。PowerMockとMockitoを使った静的なモックが機能しない

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Collections.class) 
public class MyTest { 

    @Test 
    public void testShuffle() { 
     PowerMockito.mockStatic(Collections.class); 
     PowerMockito.doCallRealMethod().when(Collections.class); 
     Collections.shuffle(Mockito.anyListOf(Something.class)); 

     ClassToTest test = new ClassToTest(); 
     test.doSomething(); 

     PowerMockito.verifyStatic(); // Verify shuffle was called exactly once 
     Collections.shuffle(Mockito.anyListOf(Something.class)); 
    } 
} 

public class ClassToTest { 
    private final List<Something> list; 
    // ... 
    public void doSomething() { 
     Collections.shuffle(list); 
     // do more stuff 
    } 
} 

上記のコードが与えられていると、私は単体テスト合格を期待しています。ただし、ユニットテストは次のように失敗します。

Wanted but not invoked java.util.Collections.shuffle([]); 
Actually, there were zero interactions with this mock. 

私は間違っていますか?

おかげ

EDIT: 私は次のことを試してみました、と私は同じエラーを取得するの下に提案を1として。

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Collections.class) 
public class MyTest { 

    @Test 
    public void testShuffle() { 
     PowerMockito.mockStatic(Collections.class); 

     ClassToTest test = new ClassToTest(); 
     test.doSomething(); 

     PowerMockito.verifyStatic(); // Verify shuffle was called exactly once 
     Collections.shuffle(Mockito.anyListOf(Something.class)); 
    } 
} 
+0

マッチャーの制限を 'anyListOf'から' any(List.class) 'に緩めるとどうなりますか? '@ PrepareForTest'アノテーションに' ClassToTest'を追加するとどうなりますか? –

答えて

4

あなたはどちらかのモック/ java.util.Collections.shuffle([])メソッドを確認するか、()(PowerMockito.doCallRealMethodで)実際の実装を呼び出すことができます。しかし、あなたは両方を行うことはできません。

あなたは

PowerMockito.doCallRealMethod().when(Collections.class); 

を削除した場合、コールが検証され、テストに合格します。

https://powermock.googlecode.com/svn/docs/powermock-1.4.7/apidocs/org/powermock/api/mockito/PowerMockito.html#doCallRealMethod%28%29

このコードは、私の作品:

package test; 

import java.util.Collections; 
import java.util.LinkedList; 
import java.util.List; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Collections.class) 
public class MyTest { 

    @Test 
    public void testShuffle() { 
     PowerMockito.mockStatic(Collections.class); 
/*  PowerMockito.doCallRealMethod().when(Collections.class); remove this line */ 
     Collections.shuffle(Mockito.anyListOf(Something.class)); 

     ClassToTest test = new ClassToTest(); 
     test.doSomething(); 

     PowerMockito.verifyStatic(); // Verify shuffle was called exactly once 
     Collections.shuffle(Mockito.anyListOf(Something.class)); 
    } 
} 

class ClassToTest { 
    private List<Something> list = new LinkedList<Something>(); 
    // ... 
    public void doSomething() { 
     Collections.shuffle(list); 
     // do more stuff 
    } 
} 
class Something { 
} 
+0

私はあなたが提案したものを試しましたが、私のテストではモックとの相互作用がゼロであるということはまだ言えません。私の編集を参照してください。 –

+0

ああありがとう...私はCollections.shuffle()と呼ばなければならない部分を逃しました...私は誓ったことはできましたが、私もそれを試みました。 –

4

これはかなり古い質問ですが、私はまだ受け入れ答えが実際に間違っていることを明確にしたいと思います。次のコードを実行することにより、

PowerMockito.mockStatic(Collections.class); 
Collections.shuffle(Mockito.anyListOf(Something.class)); 

すべての検証は常に後で渡します:

PowerMockito.verifyStatic(); // Verify shuffle was called exactly once 
Collections.shuffle(Mockito.anyListOf(Something.class)); 

をあなたは答えで提供されるテストはまだ合格するtest.doSomething();を呼び出さない場合でも。これをテストする正しい方法は、リスト内の項目が正しくソートされているかどうかを実際に確認することです。

関連する問題