调用真实方法后,PowerMockito模拟被清除

时间:2020-08-27 13:48:14

标签: java unit-testing mockito powermock localdate

使用PowerMockito静态方法模拟时,我遇到了奇怪的行为。

enter image description here

注意: 2020-08-27是执行测试时的实际系统时间。

在上面的代码示例中,您可以看到我模拟了LocalDate.now()方法的所有实现和LocalDateTime.now()方法的所有实现。我想同时实现LocalDateTime.of(LocalDate, LocalTime)方法的真正实现。

在我调用LocalDateTime.of(LocalDate, LocalTime)方法之前,所有模拟都正常工作。

在调用LocalDateTime.now()之后调用LocalDateTime.of(LocalDate, LocalTime)时,我得到的是真实系统时间,而不是第一次的模拟值。但是,如果我再次LocalDateTime.now(),那么我会再次得到模拟的时间。

上面附有调试屏幕截图,其中包含模拟结果。这是我正在使用的代码。

@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*"})
// This is needed due to a compatibility issue of Power Mock with JDK 9 (https://github.com/powermock/powermock/issues/864#issuecomment-447001997)
public class MainTest {

    @Test
    public void test() {
        LocalDate now = LocalDate.now();

        String dateString = "2020-08-24T09:00:00Z";
        Instant instant = Instant.parse(dateString);
        LocalDate localDate = LocalDate.ofInstant(instant, ZoneId.of("UTC"));
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("UTC"));

        PowerMockito.mockStatic(LocalDate.class);
        PowerMockito.when(LocalDate.now()).thenReturn(localDate);
        PowerMockito.when(LocalDate.now(Mockito.any(ZoneId.class))).thenReturn(localDate);
        PowerMockito.when(LocalDate.now(Mockito.any(Clock.class))).thenReturn(localDate);

        PowerMockito.mockStatic(LocalDateTime.class);
        PowerMockito.when(LocalDateTime.of(Mockito.any(LocalDate.class), Mockito.any(LocalTime.class))).thenCallRealMethod();
        PowerMockito.when(LocalDateTime.now()).thenReturn(localDateTime);
        PowerMockito.when(LocalDateTime.now(Mockito.any(ZoneId.class))).thenReturn(localDateTime);
        PowerMockito.when(LocalDateTime.now(Mockito.any(Clock.class))).thenReturn(localDateTime);

        LocalDate now1 = LocalDate.now();
        LocalDateTime of = LocalDateTime.of(localDate, LocalTime.of(10, 30));
        LocalDate now2 = LocalDate.now();
        LocalDate now3 = LocalDate.now();
        System.out.println("");
    }
}

我花了几个小时来寻找根本原因,但不幸的是还没有运气。有人可以告诉我这里有什么问题吗?

1 个答案:

答案 0 :(得分:0)

这看起来像是PowerMockito.mockStatic本身的错误。我也在https://github.com/powermock/powermock/issues/1066发布了相同的内容。但是我还没有得到任何回应。无论如何,我可以使用PowerMockito.stub方法为我的用例找到解决方案。以下代码段按预期工作,没有任何问题。

@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.dom.*"})
// This is needed due to a compatibility issue of Power Mock with JDK 9 (https://github.com/powermock/powermock/issues/864#issuecomment-447001997)
public class MainTest {

    @Test
    public void test() {
        LocalDate now = LocalDate.now();

        String dateString = "2020-08-24T09:00:00Z";
        Instant instant = Instant.parse(dateString);
        LocalDate localDate = LocalDate.ofInstant(instant, ZoneId.of("UTC"));
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("UTC"));

        PowerMockito.stub(PowerMockito.method(LocalDate.class, "now")).toReturn(localDate);
        PowerMockito.stub(PowerMockito.method(LocalDate.class, "now", ZoneId.class)).toReturn(localDate);
        PowerMockito.stub(PowerMockito.method(LocalDate.class, "now", Clock.class)).toReturn(localDate);

        PowerMockito.stub(PowerMockito.method(LocalDateTime.class, "now")).toReturn(localDateTime);
        PowerMockito.stub(PowerMockito.method(LocalDateTime.class, "now", ZoneId.class)).toReturn(localDateTime);
        PowerMockito.stub(PowerMockito.method(LocalDateTime.class, "now", Clock.class)).toReturn(localDateTime);

        LocalDate now1 = LocalDate.now();
        LocalDateTime of = LocalDateTime.of(localDate, LocalTime.of(10, 30));
        LocalDate now2 = LocalDate.now();
        LocalDate now3 = LocalDate.now();
        System.out.println("");
    }
}

两种方法之间的区别在于PowerMockito.mockStatic我模拟了整个类,然后使用PowerMockito.when定义了每种方法的行为。尚未用PowerMockito.when定义的方法将被返回null或不执行任何操作。但是对于PowerMockito.stub,我不会嘲笑整个课堂。我仅使用PowerMockito.stub为一组选定的方法定义模拟行为,如果调用,其他方法将调用真实方法。

相关问题