Reputation: 1610
I am facing a strange problem while trying to unit test my code.
Here is my code :
public class ItemService {
private OfferService offerService;
@Inject
public ItemService (OfferService offerService){
this.offerService = offerService;
}
public List<Item> buildItems(ItemInfo itemInfo) {
List<Item> items = processItem(itemInfo);
Offers<Offer> offers = fetchItemInfo(items);
// based on the object offers, do some processing
}
private Offers<Offer> fetchItemInfo(List<Item> items) {
Offers<Offer> offers = new Offers<>();
// some processing here with offers.
// calling the db to fetch details
offerService.fetchInfoFromDB(offers);
return offers;
}
}
public class OfferService {
public void fetchInfoFromDB(Offers<Offer> offers) {
// fetching details from DB
// and updating the object **offers**
myDao.getDetailsById(id);
}
}
Now I have written junit to test the method buildItems()
UPDATE updating the mocks used and mock injection.
@RunWith(PowerMockRunner.class)
@PrepareForTest(ItemService.class)
public class ItemServiceTest{
@Mock private MyDAO myDao;
@Mock private OfferService offerService;
@Before
public void setUp() throws Exception {
ItemService itemService = new ItemService (offerService, myDao);
}
public void testBuildItems(){
// some code -----
itemInfo = buildItemInfo();
offerDetail = buildOfferDetail();
when(myDao.getDetailsById(Mockito.anyLong())).thenReturn(offerDetail);
// some code -----
// I need to implement some code which will actually call
// offerService.fetchInfoFromDB(offers);
// and update the --offers-- object and return it.
List<Item> items = itemService.buildItems(itemInfo);
Assert.assertNotNull(items);
}
}
I am running with coverage and I can see that the below line got executed but the actual method is not getting called :
offerService.fetchInfoFromDB(offers);
I am getting null values in offers. Then I added the below line :
doCallRealMethod().when(offerService).fetchInfoFromDB(offers);
Still the same result. The offers object is passed by reference and is getting updated after the DB call which I am mocking already. But upto that call my code is not reaching. How can I update the offers object in my junit. Please help.
Upvotes: 1
Views: 1358
Reputation: 95664
Your test is calling a zero arg ItemService()
constructor, not the one arg @Inject
constructor you posted. Either your code won't compile, or you haven't actually shown us the code in question.
Also, you say you are mocking offerService
:
You call when
on myDao
and not offerService
,
you do not pass your mock offerService
into your ItemService
constructor, as in new ItemService(offerService)
, and
your doCallRealMethod
won't work because your mock offerService
won't use your mock myDao
; you'll need to mock the call on offerService
directly with a thenAnswer
that changes the passed List<Offer>
, as on my question you linked.
doAnswer(invocation -> {
((List<Offer>) invocation.getArgument(0)).add(offerDetail);
return null;
}).when(offerService).fetchInfoFromDb(any());
If you fix those three you will be considerably closer to a working test.
Upvotes: 2