简体   繁体   English

使用PowerMock和Mockito进行静态模拟无法正常工作

[英]Static mocking with PowerMock and Mockito not working

I'm trying to verify that the Collections.shuffle() method was called in one of my classes. 我正在尝试验证我的一个类中是否调用了Collections.shuffle()方法。 I read through the (little) documentation on PowerMock with Mockito and read through the other SO questions that dealt with this issue and didn't get a resolution. 我通过Mockito阅读了关于PowerMock的(小)文档,并阅读了解决这个问题的其他SO问题并没有得到解决方案。

@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
    }
}

Given the above code, I expect the unit test pass. 鉴于上面的代码,我希望单元测试通过。 However, the unit test fails as follows: 但是,单元测试失败如下:

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

What am I doing wrong? 我究竟做错了什么?

Thanks 谢谢

EDIT: As per the suggestion below I tried the following, and I get the same error. 编辑:根据下面的建议我尝试了以下,我得到了同样的错误。

@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));
    }
}

You can either mock/verify the java.util.Collections.shuffle([]) method or call the real implementation (with PowerMockito.doCallRealMethod()). 您可以模拟/验证java.util.Collections.shuffle([])方法或调用实际实现(使用PowerMockito.doCallRealMethod())。 But you can't do both. 但你不能两者兼顾。

If you remove 如果你删除

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

the call will be verified and the test will pass. 呼叫将被验证,测试将通过。

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

This code works for me: 这段代码适合我:

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 {
}

This is a rather old question, but I'd still like to clarify that the accepted answer is in fact incorrect. 这是一个相当古老的问题,但我仍然想澄清接受的答案实际上是不正确的。 By executing the following code, 通过执行以下代码,

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

all verifies will always pass afterwards: 所有验证将始终通过:

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

even if you do not call test.doSomething(); 即使你不调用test.doSomething(); the provided test in the answer will still pass. 答案中提供的测试仍然会通过。 The correct way to test this is to actually check if the items in the List have been sorted correctly. 测试此方法的正确方法是实际检查列表中的项目是否已正确排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM