Abhi
Abhi

Reputation: 21

External Mocked method returns Null in the Actual Class

When I am testing the Mocked external call, I am not seeing the mocked value of report instead it is Null and my testing is failing. I can see the Mocked value (of report) in the Test Class but not in BusinessServiceImpl class and Application(Method Return) is not modified as I expected.

My Expectation: When I mock the External call in Impl class, mocked value should be available there and rest everything else happen as if real method was called to complete the Unit Testing.

Implementation code:

package com.core.business.service.dp.fulfillment;

import com.core.business.service.dp.payment.PaymentBusinessService;

public class BusinessServiceImpl implements BusinessService { // Actual Impl Class
    private PaymentBusinessService paymentBusinessService = PluginSystem.INSTANCE.getPluginInjector().getInstance(PaymentBusinessService.class);

    @Transactional( rollbackOn = Throwable.class)
    public Application  applicationValidation (final Deal deal) throws BasePersistenceException {
        Application application = (Application) ApplicationDTOFactory.eINSTANCE.createApplication();
        //External Call we want to Mock
        String report = paymentBusinessService.checkForCreditCardReport(deal.getId());
        if (report != null) {
            application.settingSomething(true); //report is Null and hence not reaching here
        }
        return application;
    }
}

The test code:

@Test(enabled = true)// Test Class
public void testReCalculatePrepaids() throws Exception {
    PaymentBusinessService paymentBusinessService = mock(PaymentBusinessService.class);
    //Mocking External Call
    when(paymentBusinessService.checkForCreditCardReport(this.deal.getId())).thenReturn(new String ("Decline by only Me"));
    String report = paymentBusinessService.checkForCreditCardReport(this.deal.getId());
    // Mocked value of report available here
    //Calling Impl Class whose one external call is mocked
    //Application is not modified as expected since report is Null in Impl class
    Application sc = BusinessService.applicationValidation(this.deal);
}

Upvotes: 1

Views: 1794

Answers (2)

Abhi
Abhi

Reputation: 21

I got it done and I am successfully able to get the Mocked value without touching the BusinessServiceImpl class at all. Steps I followed are: 1. @Mock PaymentBusinessService paymentBusinessService = mock(PaymentBusinessService.class); 2. @InjectMocks private PaymentBusinessService paymentBusinessService = PluginSystem.INSTANCE.getPluginInjector().getInstance(PaymentBusinessService.class);

And then simply ran the above test and I could see the value of report as "Decline by only Me" in the BusinessServiceImpl and my test case passed

Upvotes: 0

atomman
atomman

Reputation: 2507

The main purpose of Mockito is to isolate the tests. As in, when you are testing your BusinessServiceImpl you should mock all its dependencies.

This is exactly what you are trying to do with your example above. Now for the mocking to work, the mocked object has to be injected into the class you are trying to test, in this case the BusinessServiceImpl.

One way of doing this is by passing the dependecy by the contructor of the class, dependency injection. Or you could look at how it can be done with Spring and ReflectionTestUtils.

Upvotes: 1

Related Questions