Powermock不会为java.time.ZonedDateTime创建模拟

时间:2016-04-28 07:29:09

标签: powermock

我尝试使用PowerMockito为java.time.ZonedDateTime创建模拟,我期待ZonedDateTime的模拟对象。相反,实际的对象正在创建,因此我无法模拟ZonedDateTime类的方法。

以下是我的代码段

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mock;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ZonedDateTime.class})
public class ZonedDateTimeTest {

    @Test
    public void test(){
        ZonedDateTime attribute = mock(ZonedDateTime.class);
        when(attribute.format(any(DateTimeFormatter.class))).thenReturn("dummy");
        //test code here
    }
}

除此之外,当我尝试打印使用以下行创建的对象时    System.out.println(attribute.toString());

我得到以下例外:

java.lang.NullPointerException at java.time.ZonedDateTime.toString(ZonedDateTime.java:2208) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:124) at org.powermock.core.MockGateway.methodCall(MockGateway.java:185)

有人可以帮我解决这个问题吗?我应该创建一个GitHub问题吗?

2 个答案:

答案 0 :(得分:1)

java.time.ZonedDateTime是最终的系统类,因此只能使用workaround进行模拟。解决方法要求使用模拟系统类的类添加到@PrepareForTest。您可以在documentation中找到更多信息。

但是如果有可能模拟系统类的事件,我建议你以不需要模拟系统类的方式重构代码。因为,不建议模拟类which you don't own.。您可以使用有意义的方法创建一个util类。

答案 1 :(得分:1)

在类中创建一个方法,如

public class SomeClass{

public static void main(String[] args) {
    LocalDateTime now = getCurrentLocalDateTime(); 
    System.out.println(now);
}

private LocalDateTime getCurrentLocalDateTime() {
    return LocalDateTime.now();
}

}

在测试类中使用

@PrepareForTest(SomeClass.class)

@RunWith(PowerMockRunner.class)

在TestCase中

LocalDateTime tommorow= LocalDateTime.now().plusDays(1);

SomeClass classUnderTest = PowerMockito.spy(new SomeClass());

PowerMockito.when(classUnderTest, "getCurrentLocalDateTime").thenReturn(tommorow);