it-roy-ru.com

Mockito when (). ThenReturn вызывает метод без необходимости

Я немного работаю над унаследованным кодом . Я написал тест, который должен перехватывать NullPointerException (поскольку он пытается вызвать метод из нулевого объекта)

@Test(expected=NullPointerException.class)
public void checkXRequirement_NullProduct_AddAction_ShouldThrowNullPointerException() throws CustomException {
  Site site = mock(Site.class);
  Product product = null;
  when(BasketHelper.getAction(request)).thenReturn(0);
  when(BasketHelper.getActionProduct(site, request)).thenReturn(product);
  BasketHelper.requiresX(request, site);

}

Соответствующие методы и переменные:

public static final int ACTION_ADD = 0;
public static final int ACTION_DELETE = 1;

protected static int getAction(HttpServletRequest a_request) {
  String sBuyProduct = a_request.getParameter(ATTRIBUTE_NAME_BUY_PRODUCT);
  String sBuyProduct = a_request.getParameter(ATTRIBUTE_NAME_BUY_PRODUCT);

  if (sBuyProduct != null) iAction = ACTION_ADD;
  else (sDelProduct != null) iAction = ACTION_DELETE;

  return iBasketAction
}

protected static Product getActionProduct(Site a_site, HttpServletRequest a_request) {

    String sBuyProduct = a_request.getParameter(ATTRIBUTE_NAME_BUY_PRODUCT);
    String sDelProduct = a_request.getParameter(ATTRIBUTE_NAME_DEL_PRODUCT);
    String sProduct = null;

    switch (getBasketAction(a_request)) {
        case BASKET_ACTION_ADD:
        sProduct = sBuyProduct;
    break;
        case BASKET_ACTION_DELETE:
        sProduct = sDelProduct;
    break;
    }

    int iProductId;
    try {
        iProductId = Integer.parseInt(sProduct);
    } catch (NumberFormatException nbrEx) {
        return null;
    }

    Product prod = getProductById(iProductId);

    if (prod.isMasterProduct()) {
        prod = getChildProduct(prod, a_site, a_request);
    }

    return prod;
}


public static boolean requiresX(HttpServletRequest request, Site site) throws CustomException {
  try{
    if (getAction(request) == ACTION_ADD) { 
    Product prod = getActionProduct(site, request);
    return prod.getType().isRequiredX();
    }  
  } catch(NullPointerException exception) {
    log.error("Error Message", exception);
  }
  return false;
}

Результатом выполнения теста jUnit является сбой с трассировкой стека:

Java.lang.Exception: Unexpected exception, expected<Java.lang.NullPointerException> but was<org.mockito.exceptions.misusing.WrongTypeOfReturnValue>
Caused by: org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Integer cannot be returned by getParameter()
getParameter() should return String#

Я неправильно истолковал, как, когда (). Тогда Возврат должен работать здесь? Я просто хочу, чтобы getAction возвращал 0, а getActionProduct возвращал null при каждом вызове. Ясно, что getParameter () вызывается, и я не знаю, почему именно.

15
Krzysztof Jarzyna

Мокито не может издеваться над статическим методом. Ваш когда проверка не действительна:

  when(BasketHelper.getAction(request)).thenReturn(0);
  when(BasketHelper.getActionProduct(site, request)).thenReturn(product);

Это еще одна причина, по которой мы хотим сократить использование статического метода, так как его трудно издеваться.

Нет более простого способа издеваться над поведением, если ваш класс остается таким. Однако, если вы хотите изменить свой дизайн и сделать оба метода нестатичными. Правильный способ использования «когда» состоит в том, чтобы применить проверку к объекту. Например:

  BasketHelper basketHelper = mock(BasketHelper.class);
  when(basketHelper.getAction(request)).thenReturn(0);
  when(basketHelper.getActionProduct(site, request)).thenReturn(product);

Но, опять же, это работает только в том случае, если вы изменили метод getAction и getProduct вашего класса на НЕСТАТИЧЕСКИЙ.

Я помню, что есть некоторые другие фреймворки для тестирования, которые поддерживают насмешливый статический метод.

14
KKKCoder

Вы можете использовать PowerMock. Сначала создайте макет класса, для которого вы вызываете статические методы -

mockStatic(BasketHelper.class);

Затем определите ваши заглушки -

when(BasketHelper.getAction(request)).thenReturn(0);
when(BasketHelper.getActionProduct(site, request)).thenReturn(product);
1
Saurabh

Это может помочь другим, кто использует аннотации. Если вы используете аннотации, возможно, вам нужно использовать @Mock вместо @InjectMocks. Потому что @InjectMocks работает как @Spy и @Mock вместе. @Spy отслеживает недавно выполненные методы, и вы можете почувствовать, что неверные данные возвращаются/вставляются .. Проверьте эти два:

https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90

http://code.google.com/p/mockito/issues/detail?id=127

0
dillip pattnaik

Я наткнулся на эту тему, пытаясь исправить ту же проблему в моих тестах.

В случае, если другие увидят эту проблему и окажутся здесь ... В моем случае это было вызвано неиспользованием аннотации @PrepareForTest для класса поддержки.

0
John Dilley