简体   繁体   中英

Mockito is not mocking but making actual call to the third party service

I am trying to mock an object which is calling third party service but my mocked class is not being used while executing my test case. Instead it makes an actual call to the third party service. Does anybody have an idea why?

My when()then() works.

Here is my integration test class:

public class CheckoutStepsAddressITest extends AbstractITest {

    //Class to be tested
    @Autowired private CheckoutStepsAddressUtil checkoutStepsAddressUtil;

    //Dependencies (will be mocked)
    private CustomerService customerService;

    //Test data
    private AddressResponse addressResponse;
    private CheckoutAddressView checkoutAddressView;
    private AddressView addressView;

    @Before
    public void setup() {
        addressResponse = createAddressResponse();
        customerService = mock(CustomerService.class);
        checkoutAddressView = new CheckoutAddressView();
        checkoutAddressView.setNewAddress(createAddressView());
        addressView = createAddressView();

    }

    public AddressResponse createAddressResponse() {
        AddressDto addressDto = new AddressDto();
        addressDto.setFirstName("tin");
        addressDto.setLastName("tin");
        addressDto.setCity("US");
        addressDto.setZipCode("10212");
        addressDto.setStreet1("street 1");
        addressDto.setStreet2("street 2");
        addressDto.setCountryCode("DE");
        addressDto.setCompany("abc");
        AddressResponse response = new AddressResponse();
        response.setAddresses(Collections.singletonList(addressDto));
        ValidationResult validationResult = new ValidationResult();
        validationResult.setValidationStatus(JsonResponseStatus.OK);
        response.setValidationResult(validationResult);
        return response;
    }

    public AddressView createAddressView() {
        AddressView addressView = new AddressView();
        addressView.setFirstName("tin");
        addressView.setLastName("tin");
        addressView.setCity("US");
        addressView.setZipCode("10212");
        addressView.setStreet1("street 1");
        addressView.setStreet2("street 2");
        addressView.setCountryCode("DE");
        addressView.setCompany("abc");
        return addressView;
    }

    @Test
    public void testCheckForCustomerAndUpdateAddress() throws UnexpectedException {
        Mockito.when(customerService.updateAddress(addressView, UUID.randomUUID(), "BILLINGADDRESS", new JsonMessages())).thenReturn(addressResponse);
         checkoutStepsAddressUtil.checkForCustomerAndUpdateAddress(UUID.randomUUID().toString(), checkoutAddressView, new JsonMessages(), UUID.randomUUID());
    }


}

and here is the actual method to test

 @Component
public class CheckoutStepsAddressUtil {

    private static final Logger LOG = LoggerFactory.getLogger(CheckoutStepsAddressUtil.class);

    @Autowired private CustomerService customerService;
    @Autowired private UrlBuilder urlBuilder;
    @Autowired private CustomerViewBuilder customerViewBuilder;
    @Autowired private CheckoutViewBuilder checkoutViewBuilder;
    @Autowired private CheckoutUtil checkoutUtil;
    @Autowired private OfferService offerService;

 public AddressView checkForCustomerAndUpdateAddress(String addressId, CheckoutAddressView checkoutView, JsonMessages messages, UUID customerId) throws UnexpectedException {
        LOG.info("Entering");
        AddressView addressView = null;
        //check if the customer Id is null, if yes then return the error response else proceed to update
        if (customerId == null) {
            messages.addError(CheckoutStepAjaxControllerConstants.SHOP_CHECKOUT_ADDRESSES_MISSING_OFFER_OR_CUSTOMER);
            LOG.info("Failed to store address because of missing customer");
        } else {
            //Trims the empty field values to null and proceed to update
            checkoutUtil.trimEmptyAddressFieldsToNull(checkoutView);
            addressView = updateAddressAndCheckAddressValidationResult(addressId, checkoutView, messages, customerId);
        }
        return addressView;
    }

    /**
     * Calls Customer service to update the address and then checks the Validation Result with status`ERROR`
     * and adds them to `JsonMessages`
     *
     * @param addressId    id of the address to be updated
     * @param checkoutView view that has the address to update
     * @param messages
     * @param customerId
     * @return AddressView
     * @throws UnexpectedException
     */
    private AddressView updateAddressAndCheckAddressValidationResult(String addressId, CheckoutAddressView checkoutView, JsonMessages messages, UUID customerId) throws UnexpectedException {
        AddressView address = checkoutView.getNewAddress();
        address.setAddressId(addressId);
        String identifier = OfferAddressType.NEW.toLower() + ADDRESS;
        AddressResponse addressResponse = customerService.updateAddress(address, customerId, identifier, messages);

        checkAddressValidationResponseFromCustomer(messages, identifier, addressResponse);
        return address;
    }

UPDATED: Solved my problem by doing this

@RunWith(MockitoJUnitRunner.class)
public class CheckoutStepsAddressUtilITest extends AbstractITest {

//Mock all the dependencies here
@Mock
private CustomerService customerService;
@Mock
private UrlBuilder urlBuilder;
@Mock
private CustomerViewBuilder customerViewBuilder;
@Mock
private CheckoutViewBuilder checkoutViewBuilder;
@Mock
private CheckoutUtil checkoutUtil;
@Mock
private OfferService offerService;

//Injects all the dependencies
@InjectMocks
private CheckoutStepsAddressUtil checkoutStepsAddressUtil;

//Test data
private AddressResponse addressResponse;
private CheckoutAddressView checkoutAddressView;
private AddressView actualAddressView;

@Before
public void setup() {
    addressResponse = createAddressResponse();
    checkoutAddressView = new CheckoutAddressView();
    checkoutAddressView.setNewAddress(createAddressView());
    actualAddressView = createAddressView();
}

@Test
    public void testCheckForCustomerAndUpdateAddress() throws UnexpectedException {
        Mockito.when(customerService.updateAddress(any(), any(), anyString(), any())).thenReturn(addressResponse);
        AddressView expectedAddressView = checkoutStepsAddressUtil.checkForCustomerAndUpdateAddress(UUID.randomUUID().toString(), checkoutAddressView, new JsonMessages(), UUID.randomUUID());
        assertNotNull(expectedAddressView);
        assertEquals(actualAddressView.getFirstName(), expectedAddressView.getFirstName());
    }

The customer service that is called is not the one you mock.

The Autowire annotation of your service in your test wires all the services with the same annotation in you CheckoutStepsAddressUtil. Which means that when you run your tests, Spring has no way of knowing that it should replace the customerService instance by your mock. Hence the call to the actual service.

You need a way to inject your mocked service into the service you want to test.

One way to do it is through ReflectionTestUtils , adding this line to your test before the actual call to your tested method should do the trick:

ReflectionTestUtils.setField(checkoutStepsAddressUtil, "customerService", customerService);

Note that in this case you are still autowiring the other dependencies of your service so may still have a problem with other calls.

Some of the objects that use in the when.then are not the same ones that are actually passed to this method during execution. I would play around with wildcards here:

@Test
    public void testCheckForCustomerAndUpdateAddress() throws UnexpectedException {
       UUID uuid = UUID.randomUUID();

       Mockito.when(customerService.updateAddress(
             eq(addressView), eq(uuid), eq("BILLINGADDRESS"), any(JsonMessages.class))
         .thenReturn(addressResponse);

         checkoutStepsAddressUtil.checkForCustomerAndUpdateAddress(uuid.toString(),checkoutAddressView, new JsonMessages(), uuid );
    }

Used: Mockito.any(), Mockito.eq() ;

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM