Reputation: 6293
Running this test:
@Test
public void testSystemCurrentTimeMillis() {
new NonStrictExpectations(System.class) {{
System.currentTimeMillis(); result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
}
I get an 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$1.(DateTest.java:24) at unittests.DateTest.testSystemCurrentTimeMillis(DateTest.java:23)
What's wrong with my Test (JMockit 1.18)?
Upvotes: 3
Views: 11229
Reputation: 1750
I use PowerMock for this:
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();
}
Of course you put whatever you wish in the invocation.
Upvotes: 0
Reputation: 69
Yeah this is partial mocking. With small correction in the nonStrictExpectation(){} your above mentioned code can also get fix:
@Mocked
private System system;
new NonStrictExpectations() {{
System.currentTimeMillis();
result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
This should also work.
Upvotes: 0
Reputation: 6293
My final solution is to create a MockUp for System, that only mocks the method 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);
}
Upvotes: 3
Reputation: 69
This thing has been introduced in JMockit version 1.17 only to use object reference with your NonStrictExpectation(){} block,Deprecated attribute value for 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.
Please refer the below link: JMockit version history
Upvotes: 1
Reputation: 2826
Like so many things with JMockit, it's easy enough to do. Try this..
@Test
public void testSystemCurrentTimeMillis(@Mocked final System unused) {
new NonStrictExpectations() {{
System.currentTimeMillis(); result = 1438357206679L;
}};
long currentTime = System.currentTimeMillis();
assertEquals(1438357206679L, currentTime);
}
Found this site to be an excellent reference, by the way. Probably you were tripped up by the static method. All you need to do is declare the class with the static method as mocked--you never need to refer to the variable, hence I named it "unused".
Upvotes: 2