我尝试使用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问题吗?
答案 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);