使用Mockito进行单元测试 - 忽略方法调用

时间:2013-03-13 16:03:41

标签: java unit-testing mockito

我很高兴学习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返回的内容。因为当false为0时它返回result,并且如果它是任何数字但是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的返回值而不实际调用它来测试上述方法。

2 个答案:

答案 0 :(得分: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"));
    }
}

但你不应该使用间谍。你应该将class重构为两个,这样你就可以测试一个对另一个的模拟。

答案 1 :(得分:0)

您无法在Mocked类中测试代码。如果你只是模拟它,所有的方法都是存根。

你必须反而间谍。阅读有关如何使用间谍的Mockito文档。