2013-07-30 56 views
5

我想驗證Collections.shuffle()方法是在我的一個類中調用的。我用Mockito閱讀了關於PowerMock的(少量)文檔,並閱讀了解決這個問題的其他SO問題,但沒有得到解決方案。StaticMocking與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. 

我在做什麼錯?

感謝

編輯: 按下面我嘗試以下,我也得到了同樣的錯誤的建議。

@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)'中,會發生什麼?如果將'ClassToTest'添加到'@ PrepareForTest'註釋中會發生什麼? –

回答

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();在回答所提供的測試仍然會通過。測試的正確方法是實際檢查列表中的項目是否已正確排序。

相關問題