In my class under test there is a @PostConstruct
annotated method that invokes another private method.
@PostConstruct
public void init() {
longWork(); // private method
}
JMockit's default behaviour is to execute @PostConstruct
methods of @Tested
classes upon injection.
If a @Tested class has a method annotated with javax.annotations.PostConstruct, it should be executed right after injection.
https://github.com/jmockit/jmockit1/issues/13
JMockit calls the init()
method, what I don't want.
From the thread dump:
at com.me.Worker.longWork(Worker.java:56)
at com.me.Worker.longWork.init(Worker.java:47)
...
at mockit.internal.util.MethodReflection.invoke(MethodReflection.java:96)
How can that call be mocked/removed/blocked?
I tried to mock the init
and longWork
methods as shown below. However that results in NullPointerException
as sut
is not injected yet.
@Before
public void recordExpectationsForPostConstruct()
{
new NonStrictExpectations(sut) {{ invoke(sut, "init"); }};
}
You can try manually initializing your class to be tested without using @Tested. And then, set mock dependencies via setter methods (or using mockit.Deencapsulation.setField() method).
You can try something similar to this;
//Define your class under test without any annotation
private MyServiceImpl serviceToBeTested;
//Create mock dependencies here using @Mocked like below
@Mocked Dependency mockInstance;
@Before
public void setup() {
//Initialize your class under test here (or you can do it while declaring it also).
serviceToBeTested = new MyServiceImpl();
//Set dependencies via setter (or using mockit.Deencapsulation.setField() method)
serviceToBeTested.setMyDependency(mockInstance);
//Optionally add your expectations on mock instances which are common for all tests
new Expectations() {{
mockInstance.getName(); result = "Test Name";
...
}};
}
@Test
public void testMyMethod(@Mocked AnotherDependency anotherMock) {
//Add your expectations on mock instances specifics to this test method.
new Expectations() {{
mockInstance.getStatus(); result = "OK";
anotherMock.longWork(); result = true;
...
}};
//Set dependencies via setter or using mockit.Deencapsulation.setField() method
Deencapsulation.setField(serviceToBeTested, "myAnotherDep", anotherMock);
//Invoke the desired method to be tested
serviceToBeTested.myMethod();
//Do the verifications & assertions
new Verifications() {{
....
....
}};
}
Perhaps you could delegate the longWork method to a different class and mock this one. Difficulties while writing tests is often a sign of design flaws
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.