简体   繁体   English

Mockito不是在嘲笑,而是实际致电第三方服务

[英]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. 我的when()then()有效。

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. 测试中服务的自动装配注释将所有服务连接到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. 这意味着当您运行测试时,Spring无法得知应该用您的模拟代替customerService实例。 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 ,在实际调用被测方法之前,应在测试中添加以下代码:

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. when.then中使用的某些对象与执行期间实际传递给此方法的对象不同。 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() ; 使用的: Mockito.any(), Mockito.eq() ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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