Reputation: 49
In my class, dependencies are injected by Spring. During testing, I am using mocks. I am getting null pointer exception when I call sys.getId("abc12345")
in the following code. I am wondering how to write a unit test that gets 100% coverage.
Class under test:
public class SystemUT implements SUTIface{
@Inject
private AccountLookupDAO dao;
@Inject
private OrchService service;
public Response perform(Request req){
String sellerId = getId(request.getSeller().getNum());
String buyerId = null;
if(req.getBuyerId){
buyerId = getId(request.getBuyer().getNum())
}
service.execute(Request,sellerId,buyerId)
}
String getId(String num){
PrefAcct prefAcctObj = dao.lookupPrefId(num,Consants.StrArr);
PrefSysOfRecObj sorObj= prefAcctObj.getSysOfRecord();
return sorObj.getId();
}
}
Unit test:
public Class SystemUTTest{
@Mock
SystemUT sys;
@Mock
AccountLookupDAO daoMock;
@Mock
OrchService serviceMock;
@Mock
PrefAcct prefAcctObj;
@Mock
PrefSysOfRecObj sorObj;
@Before
public void setup(){
Whitebox.setInternalState(sys, daoMock, serviceMock);
}
@Test
public test getId(){
when(dao.lookupPrefId(any(String.class), any(String[].class))).thenReturn(prefAcctObj);
when(prefAcctObj.getSysOfRecord()).thenReturn(sorObj);
when(sorObj.getId()).thenReturn("185");
assertEquals("185",sys.getId("abc12345"));
}
}
Upvotes: 1
Views: 1026
Reputation: 59699
Your problem is that your SystemUT
class doesn't have its dependencies injected. You could have Spring do this by using their JUnitRunner, but it's not really a unit test then, since you'd be letting Spring dictate which dependencies get injected. Really, you want to control them, and one way to do that is to transform your class to expose its dependencies via a constructor:
public class SystemUT implements SUTIface{
private final AccountLookupDAO dao;
private final OrchService service;
@Inject
public SystemUT(AccountLookupDAO dao, OrchService service) {
this.dao = dao;
this.service = service;
}
}
This will function identically to your current approach since Spring is able to inject dependencies using a constructor annotated with @Inject
. Now, when you instantiate your SystemUT
class for test, pass mocked objects for its dependencies:
@Mock
AccountLookupDAO daoMock;
@Mock
OrchService serviceMock;
private SystemUT sys;
@Before
public void setup(){
sys = new SystemUT(daoMock, serviceMock);
Whitebox.setInternalState(sys, daoMock, serviceMock);
}
Upvotes: 2