2013-08-20 91 views
13

我在繼承代碼上工作了一下。 我已經寫了應該趕上NullPointerException異常測試(因爲它試圖調用從空對象的方法)Mockito when()。thenReturn調用方法不必要

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

不要誤解我的時候()thenReturn應該如何工作的他。回覆?我只想讓getAction返回0,getActionProduct在它被調用時返回null。很明顯getParameter()被調用,我不知道爲什麼。

+0

你可以顯示'getProduct()'? –

+0

在其他新聞.... 我可以看到你爲什麼會寫這種測試來複制一個問題。然而,真正的測試應該是驗證如果''''''''''爲null,''''requireX'''方法不會被調用。除非你的繼承代碼使用npe來控制代碼流?在這種情況下 - 撕掉這一點。 – OceanLife

+0

我認爲你是對的。在requiresX方法中改變條件可能是一個好主意。 –

回答

13

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方法是非靜態這只是工作。

我記得還有一些其他測試框架支持模擬靜態方法。

+2

我認爲PowerMock允許模擬靜態方法。也許我應該看看它。謝謝 –

+0

看起來像是:-)祝你好運。 – KKKCoder

+0

你可以看看PowerMock。或者你可以重構你的代碼以避免使用靜態方法。我會推薦後者。 –

1

您可以使用PowerMock。首先創建一個用於呼籲靜態方法類的模擬 -

mockStatic(BasketHelper.class); 

然後定義您的存根 -

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

我碰到這個線程運行,同時試圖解決同樣的問題,在我的測試。

如果其他人看到這個問題,並最終在這裏......在我的情況下,它是由於沒有使用支持類的@PrepareForTest批註引起的。

相關問題