java dothrow Mockito when()。thenReturnが不必要にメソッドを呼び出す




mockito void throw (4)

あなたはPowerMockを使うことができます。 最初にあなたが静的メソッドを呼び出しているクラスのモックを作成します -

mockStatic(BasketHelper.class);

それからあなたのスタブを定義します -

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

私は継承されたコードに少し取り組んでいます。 NullPointerExceptionをキャッチすることになっているテストを書いた(nullオブジェクトからメソッドを呼び出そうとしているため)

@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#

when()がthenReturnがここで機能することになっていると誤解していませんか? getActionが0を返し、getActionProductが呼び出されるたびにnullを返すようにしたいだけです。 明らかにgetParameter()が呼ばれていますが、その理由はわかりません。


Answer #1

私のテストで同じ問題を解決しようとしながら、私はこのスレッドに出くわしました。

他の人がこの問題を見てここで終わる場合...私の場合は、サポートクラスに@PrepareForTestアノテーションを使用していないことが原因でした。


Answer #2

Mockitoは静的メソッドをモックすることはできません。 あなたのいつチェックが有効ではありません:

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

それがモックするのが難しいので静的メソッドの使用を減らしたいのはそれが別の理由です。

あなたのクラスがこのようなままであるならば、振る舞いを偽造するより簡単な方法はありません。 ただし、デザインを変更して両方の方法を非静的にする場合は、 "when"の正しい使い方は、モックオブジェクトにチェックを適用することです。 例えば:

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

しかし、これもまた、クラスのgetActionメソッドとgetProductメソッドをNON-STATICに再設計した場合にのみ機能します。

静的メソッドのモックをサポートするテストフレームワークが他にもいくつかあることを私は覚えています。


Answer #3

これはアノテーションを使う人を助けるかもしれません。 注釈を使用している場合は、@ InjectMocksの代わりに@Mockを使用する必要があるかもしれません。 @InjectMocksは@Spyと@Mockの両方として機能するためです。 そして@Spyは最近実行されたメソッドを追跡し続けます、そしてあなたは不正確なデータが返されたり/奪われているのを感じるかもしれません。 次の2つを確認してください。

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

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





mockito