Mockito - не издевательство, а фактический звонок в стороннюю службу - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь смоделировать объект, который вызывает стороннюю службу, но мой проверяемый класс не используется при выполнении моего тестового примера. Вместо этого он выполняет фактический вызов сторонней службы. У кого-нибудь есть идея, почему?

Мой when()then() работает.

Вот мой класс интеграционных испытаний:

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());
    }


}

и вот фактический метод для проверки

 @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;
    }

ОБНОВЛЕНО: Решив мою проблему, сделав это

@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());
    }

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Служба поддержки клиентов, которую вы вызываете, не является той, над которой вы издеваетесь.

Аннотация Autowire вашего сервиса в вашем тесте связывает все сервисы с такой же аннотацией в вас CheckoutStepsAddressUtil.Это означает, что когда вы запускаете свои тесты, у Spring нет возможности узнать, что он должен заменить экземпляр customerService вашим макетом.Отсюда обращение к фактическому сервису.

Вам нужен способ внедрить ваш фиктивный сервис в сервис, который вы хотите протестировать.

Один из способов сделать это - через ReflectionTestUtils , добавив эту строку в ваш тест до того, как фактический вызов вашего тестируемого метода должен выполнить свою задачу:

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

Обратите внимание, что в этом случае вы все еще автоматически подключаете другие зависимости вашего сервиса, поэтому у вас все еще может бытьпроблема с другими звонками.

0 голосов
/ 11 июля 2019

Некоторые объекты, которые используются в when.then, не являются теми же, которые фактически передаются этому методу во время выполнения.Я бы поиграл с подстановочными знаками здесь:

@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 );
    }

Используется: Mockito.any(), Mockito.eq();

...