JMockit 模拟 System.currentTimeMillis()
JMockit mocking System.currentTimeMillis()
运行本次测试:
@Test
public void testSystemCurrentTimeMillis() {
new NonStrictExpectations(System.class) {{
System.currentTimeMillis(); result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
}
我得到一个 IllegalStateException:
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter
at unittests.DateTest.(DateTest.java:24)
at unittests.DateTest.testSystemCurrentTimeMillis(DateTest.java:23)
我的测试 (JMockit 1.18) 有什么问题?
就像 JMockit 的许多事情一样,它很容易做到。试试这个..
@Test
public void testSystemCurrentTimeMillis(@Mocked final System unused) {
new NonStrictExpectations() {{
System.currentTimeMillis(); result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
}
发现 this 网站是一个很好的参考,顺便说一下。可能您被静态方法绊倒了。您需要做的就是使用静态方法将 class 声明为 mocked——您永远不需要引用该变量,因此我将其命名为 "unused".
这个东西在 JMockit 1.17 版中引入只是为了在你的 NonStrictExpectation(){} 块中使用对象引用,Mocked 的弃用属性值
Deprecated the "value" attribute of @Mocked, which is used for "static" partial mocking. Existing uses should be replaced with "dynamic" partial mocking, by passing the instance or class to partially mock in a call to the Expectations(Object...) constructor, or by applying a MockUp class.
请参考以下link: JMockit version history
我的最终解决方案是为 System 创建一个 MockUp,它只模拟方法 currentTimeMillis():
private static class SystemMock extends MockUp<System> {
@Mock
public static long currentTimeMillis() {
return 10000000L;
}
}
@Test
public void testAddNowDate() {
new SystemMock();
long currentTime = System.currentTimeMillis();
assertEquals(10000000L, currentTime);
}
是的,这是部分嘲讽。通过在 nonStrictExpectation(){} 中进行小的修正,您上面提到的代码也可以得到修复:
@Mocked
private System system;
new NonStrictExpectations() {{
System.currentTimeMillis();
result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
这应该也可以。
我为此使用 PowerMock:
private void configureSystemClockMock(final int clockJump) {
AtomicInteger callCount = new AtomicInteger();
Answer<Integer> answer = invocation -> {
callCount.addAndGet(1);
return callCount.get() * clockJump;
};
PowerMockito.mockStatic(System.class);
PowerMockito.doAnswer(answer).when(System.class);
System.currentTimeMillis();
}
当然你可以在调用中放任何你想放的东西。
运行本次测试:
@Test
public void testSystemCurrentTimeMillis() {
new NonStrictExpectations(System.class) {{
System.currentTimeMillis(); result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
}
我得到一个 IllegalStateException:
java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter at unittests.DateTest.(DateTest.java:24) at unittests.DateTest.testSystemCurrentTimeMillis(DateTest.java:23)
我的测试 (JMockit 1.18) 有什么问题?
就像 JMockit 的许多事情一样,它很容易做到。试试这个..
@Test
public void testSystemCurrentTimeMillis(@Mocked final System unused) {
new NonStrictExpectations() {{
System.currentTimeMillis(); result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
}
发现 this 网站是一个很好的参考,顺便说一下。可能您被静态方法绊倒了。您需要做的就是使用静态方法将 class 声明为 mocked——您永远不需要引用该变量,因此我将其命名为 "unused".
这个东西在 JMockit 1.17 版中引入只是为了在你的 NonStrictExpectation(){} 块中使用对象引用,Mocked 的弃用属性值
Deprecated the "value" attribute of @Mocked, which is used for "static" partial mocking. Existing uses should be replaced with "dynamic" partial mocking, by passing the instance or class to partially mock in a call to the Expectations(Object...) constructor, or by applying a MockUp class.
请参考以下link: JMockit version history
我的最终解决方案是为 System 创建一个 MockUp,它只模拟方法 currentTimeMillis():
private static class SystemMock extends MockUp<System> {
@Mock
public static long currentTimeMillis() {
return 10000000L;
}
}
@Test
public void testAddNowDate() {
new SystemMock();
long currentTime = System.currentTimeMillis();
assertEquals(10000000L, currentTime);
}
是的,这是部分嘲讽。通过在 nonStrictExpectation(){} 中进行小的修正,您上面提到的代码也可以得到修复:
@Mocked
private System system;
new NonStrictExpectations() {{
System.currentTimeMillis();
result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
这应该也可以。
我为此使用 PowerMock:
private void configureSystemClockMock(final int clockJump) {
AtomicInteger callCount = new AtomicInteger();
Answer<Integer> answer = invocation -> {
callCount.addAndGet(1);
return callCount.get() * clockJump;
};
PowerMockito.mockStatic(System.class);
PowerMockito.doAnswer(answer).when(System.class);
System.currentTimeMillis();
}
当然你可以在调用中放任何你想放的东西。