【问题标题】:Java power mock unit test a method having Thread.SleepJava 电源模拟单元测试具有 Thread.Sleep 的方法
【发布时间】:2019-10-10 13:00:31
【问题描述】:

我正在尝试对调用 Thread.sleep 的方法进行单元测试。

public Boolean waitForUpscale(){
   String res = someObject.upTheResources();
   Thread.sleep(20000);
   Boolean status = someObject.checkForStatus();
   return status;
}

在测试此测试时,由于Thread.sleep 我必须避免测试在测试时进入睡眠状态。

更新:

我添加了这个测试:

@Test
    public void downscaleTest() throws Exception {
        when(someservice.downScaleResources()).thenReturn("DONE");
        PowerMockito.mockStatic(Thread.class);
        doNothing().when(Thread.class, "sleep", anyLong());
        Boolean res = Whitebox.invokeMethod(myController, "downscaleALL");

        assertTrue(res);
    }

当我调试它时,它可以工作。但是当我正常运行测试时,它会出现以下异常:

0 matchers expected, 1 recorded:

-> at com.mypackage.controller.MyController.downscaleALL(MyControllerTest.java:265)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.



添加 downScaleAll 方法

private Boolean downscaleALL() {
    try {
        String downScaleResources = someservice.downScaleResources();
        if (downScaleResources.equals("DONE")) {
            Thread.sleep(20000); // 20s
            log.info("DOWNSCALING THE RESOURCES NOW");
            return true;
        }

        return false;
    } catch (Exception e) {
        log.error("Error while downscaling the resources");
        log.error(e.toString());
        return false;
    }
}

【问题讨论】:

  • 你添加prepareForTest注解了吗?没有完整的测试类,很难提供帮助
  • 是的,我有 @PrepareForTest({MyController.class, Thread.class})
  • 你可以添加你正在调用的控制器类的downscaleALL方法
  • 添加downscaleALL方法
  • 你能不能也把你的完整测试课。你如何将一些服务模拟注入你的控制器?还有为什么你用whitebox来调用,你可以直接调用mycontroller.downscaleAll()不是吗?

标签: java unit-testing powermock


【解决方案1】:

您应该只使用mock types you own,因此,如果您想模拟对Thread.sleep() 的调用,您应该将其提取到您拥有的类型中(例如ThreadSleeper),因此可以模拟。更好的是,如果可以的话,重写以避免睡眠。睡眠通常是一种代码味道(偷工减料)。

【讨论】:

    【解决方案2】:

    我同意@Elevate 提到的,你不应该嘲笑你不拥有的类型。但是如果还得做的话,可以这样做

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({<ClassWherewaitForUpscaleFunctionisLocated>.class, Thread.class})
    public class Mytest {
        @Test
        public void testStaticVoid() throws Exception {
    
            PowerMockito.mockStatic(Thread.class);
            doNothing().when(Thread.class, "sleep", anyLong());
            .........
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-16
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      • 1970-01-01
      • 2019-09-14
      相关资源
      最近更新 更多