2013-03-13 154 views
4

Im struggeling學習Mockito單元測試應用程序。下面是該方法的IM的例子目前正在測試單元測試與Mockito - 忽略方法調用

public boolean validateFormula(String formula) { 

    boolean validFormula = true; 
    double result = 0; 

    try { 
     result = methodThatCalculatAFormula(formula, 10, 10); 
    } catch (Exception e) { 
     validFormula = false; 
    } 

    if (result == 0) 
     validFormula = false; 
    return validFormula; 
} 

這個方法調用在同一個班級,methodThatCalculatAFormula,這是我不希望當我單元測試validateFormula調用另一個方法。

爲了測試這個,我想看看這個方法的行爲取決於methodThatCalculatAFormula返回的結果。由於它在result爲0時返回false,並且如果它是0但是返回有效數字,我希望模擬這些返回值而不運行實際的methodThatCalculatAFormula方法。

我寫了下面的:

public class FormlaServiceImplTest { 
    @Mock 
FormulaService formulaService; 

@Before 
public void beforeTest() { 
    MockitoAnnotations.initMocks(this); 
} 

@Test 
public void testValidateFormula() {     

`//Valid since methodThatCalculatAFormula returns 3`  
when(formulaService.methodThatCalculatAFormula(anyString(),anyDouble(),anyDouble(),anyBoolean())).thenReturn((double)3);   
     assertTrue(formulaService.validateFormula("Valid"));  



//Not valid since methodThatCalculatAFormula returns 0 
when(formulaService.methodThatCalculatAFormula(anyString(),anyDouble(),anyDouble(),anyBoolean())).thenReturn((double)0); 
    assertFalse(formulaService.validateFormula("Not Valid")); 
} 

然而,當我運行上面的代碼我assertTruefalse。我猜我在模擬設置中做了錯誤的事。如何通過模擬methodThatCalculatAFormula的返回值而不實際調用它來測試上述方法。

回答

4

你試圖做的不是模擬,而是間諜(部分模擬)。你不想嘲笑一個對象,但只是一種方法。

這工作:

public class FormulaService { 
    public boolean validateFormula(String formula) { 

     boolean validFormula = true; 
     double result = 0; 

     try { 
      result = methodThatCalculatAFormula(formula, 10, 10); 
     } catch (Exception e) { 
      validFormula = false; 
     } 

     if (result == 0) 
      validFormula = false; 
     return validFormula; 
    } 

    public double methodThatCalculatAFormula(String formula, int i, int j){ 
     return 0; 
    } 
} 

public class FormulaServiceImplTest { 

    FormulaService formulaService; 

    @Test 
    public void testValidateFormula() { 

     formulaService = spy(new FormulaService()); 
     // Valid since methodThatCalculatAFormula returns 3` 
     doReturn((double) 3).when(
       formulaService).methodThatCalculatAFormula(anyString(), 
         anyInt(), anyInt()); 
     assertTrue(formulaService.validateFormula("Valid")); 

     // Not valid since methodThatCalculatAFormula returns 0 
     doReturn((double)0).when(
       formulaService).methodThatCalculatAFormula(anyString(), 
         anyInt(), anyInt()); 
     assertFalse(formulaService.validateFormula("Not Valid")); 
    } 
} 

但你不應該使用間諜。你應該將課程重構爲兩個,這樣你就可以對另一個進行模擬測試。

+0

間諜命令工作正常。據我所知,它只是嘲笑指定的方法,這使得它可以測試,即使它是一個模擬。 – 2013-03-14 08:40:06

+0

是的,並確保使用語法doReturn(result).when(spy).method()而不是when(spy.method())。doReturn(result)。後一個將不起作用,因爲它會在定義模擬方法之前調用原始方法 – rcomblen 2013-03-14 08:55:10

+0

是的,我注意到,因爲我得到了一個UnfinishedStubbException,我用Google搜索並找到了答案。 – 2013-03-14 09:04:44

0

您無法在Mocked類中測試代碼。如果你只是嘲笑它,所有的方法都是存根。

你必須反觀它。閱讀關於如何使用Spy的Mockito文檔。