Here are the brief codes of my project, class Foo:
public class Foo {
@Autowired
protected Mapper mapper;
protected User getUser() {
// ...
return user;
}
}
class Bar that extends Foo:
public class Bar extends Foo{
public void func(String param1, String param2) {
Result result = this.validateParams(param1, param2);
// ...
Entity entity = super.mapper.mapTo(param1, Entity.class);
entity.setUserInfo(super.getUser().getInfo()); // null pointer exception
}
private Result validateParams(String param1, String param2) {
// ...
return Result.success();
}
}
and the test class:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore( {"javax.management.*", "javax.net.ssl.*"})
@PrepareForTest({Bar.class}) // to mock private method
public class BarTest {
@InjectMocks
Bar bar;
@Mock
Mapper mapper;
@Test
public void testFunc() {
bar = PowerMockito.spy(bar);
bar.mapper = mapper; // or bar.mapper is null
PowerMockito.doReturn(Result.success()).when(bar, validateParams, any(), any()); // mock private method
User user = new User(); // mock user
PowerMockito.doReturn(user).when(bar).getUser(); // doesn't work
bar.func("param1", "param2");
}
}
It's weird that when I test bar.func, when it comes to entity.setUserInfo(super.getUser().getInfo()), super.getUser() return null, causing a NPE. But I've already mocked getUser() function, which seems to not work.
Looking forward for your advice & help, thanks a lot.
I tried to avoid using spy(bar), assuming that it would cause a empty copy of instance(which is all null). Also I tried to use
Method methodGetUser = PowerMockito.method(Bar.class, "getUser");
PowerMockito.replace(methodGetUser).with(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return user;
}
});
but doesn't work as well(NPE).
@InjectMocks Bar bar;creates an instance already.bar = PowerMockito.spy(bar);assigns a new instance. The originalbarinstance does not know anything about the wrapping spy. So any behavior you define on the spy (withPowerMockito.doReturn(user).when(bar).getUser();) is not visible nor accessible from within your original instance.You must keep the original reference around:
But why are you spying? You are not verifying any calls on your spy?
Related: Why are my mocked methods not called when executing a unit test?