【问题标题】:Mocking SecureRandom::nextInt()模拟 SecureRandom::nextInt()
【发布时间】:2014-04-29 21:32:41
【问题描述】:

我有一个使用 SecureRandom 实例并获取下一个随机数的类。

假设例子是:

public class ExampleClass() {
   public void method() { 
      Random sr = new SecureRandom();
      System.out.printf("%d %n", sr.nextInt(1));
      System.out.printf("%d %n", sr.nextInt(1));
   }
}

测试代码

@RunWith(PowerMockRunner.class)
public class ExampleClassTest {
...
@Test
@PrepareOnlyThisForTest(SecureRandom.class)
public void mockedTest() throws Exception {

    Random spy = PowerMockito.spy(new SecureRandom());

    when(spy, method(SecureRandom.class, "nextInt", int.class))
            .withArguments(anyInt())
            .thenReturn(3, 0);


    instance.method();
}

当我尝试运行单元测试时,单元测试最终会冻结。当我尝试仅调试该方法时,JUnit 报告该测试不是该类的成员。

No tests found matching Method mockedTest(ExampleClass) from org.junit.internal.requests.ClassRequest@6a6cb05c 

编辑:将 @PrepareOnlyThisForTest 移动到 PerpareForTests 到类的顶部修复了冻结问题。但是我遇到的问题是该方法没有被嘲笑。

【问题讨论】:

    标签: java unit-testing junit mockito powermock


    【解决方案1】:

    尝试在测试的类级别使用@PrepareForTest,而不是在方法级别。

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(SecureRandom.class) 
    public class ExampleClassTest {
    ...
    }
    

    编辑:为了调用模拟,您需要执行以下操作:

    1) 将 ExampleClass 添加到 PrepareForTest 注解中:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({SecureRandom.class, ExampleClass.class}) 
    public class ExampleClassTest {
    ...
    }
    

    2) 模拟 SecureRandom 的构造函数调用:

    SecureRandom mockRandom = Mockito.mock(SecureRandom.class);
    PowerMockito.whenNew(SecureRandom.class).withNoArguments().thenReturn(mockRandom);
    

    下面给出了一个工作示例:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({SecureRandom.class, ExampleClass.class})
    public class ExampleClassTest {
    
        private ExampleClass example = new ExampleClass();
    
        @Test
        public void aTest() throws Exception {
    
            SecureRandom mockRandom = Mockito.mock(SecureRandom.class);
           PowerMockito.whenNew(SecureRandom.class).withNoArguments().thenReturn(mockRandom);
            Mockito.when(mockRandom.nextInt(Mockito.anyInt())).thenReturn(3, 0);
            example.method();
       }
    }
    

    【讨论】:

    • 这行得通,但现在我遇到了 SecureRandom 调用本机实现而不是模拟的问题。
    • 成功了!谢谢!!在 Python 上的 mocker 和 java 中的 Mockito/Powermock 之间,我有很多习惯。
    猜你喜欢
    • 1970-01-01
    • 2017-02-08
    • 2016-11-05
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    相关资源
    最近更新 更多