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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15390422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 19:25:35  来源:igfitidea点击:

Unittest with Mockito - Ignore method call

javaunit-testingmockito

提问by John Snow

Im struggeling to learn Mockito to unittest a application. Below is a example of the method im currently trying to test

我正在努力学习 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;
}

This method calls another method in the same class, methodThatCalculatAFormula, which I do not want to call when i unittest validateFormula.

这个方法调用同一个类中的另一个方法methodThatCalculatAFormula,我不想在我单元测试时调用它validateFormula

To test this, I would like to see how this method behaves depending on what methodThatCalculatAFormulareturns. Since it returns falsewhen resultis 0, and returns valid if it's any number but 0 I would like to simulate these returnvalues without running the actual methodThatCalculatAFormulamethod.

为了测试这一点,我想看看这个方法根据methodThatCalculatAFormula返回的内容如何表现。由于它falseresult为 0时返回,如果它是除 0 之外的任何数字,则返回有效,我想在不运行实际methodThatCalculatAFormula方法的情况下模拟这些返回值。

I have written the following:

我写了以下内容:

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"));
}

However when I run the above code my assertTrueis false. Im guessing i've done something wrong in my mock setup. How would I test the above method by simulating the return value of methodThatCalculatAFormulawithout actually calling it.

但是,当我运行上面的代码时,我assertTruefalse. 我猜我在模拟设置中做错了什么。我将如何通过模拟 的返回值methodThatCalculatAFormula而不实际调用它来测试上述方法。

采纳答案by rcomblen

What you're trying to do is not a mock but a spy (partial mock). You don't want to mock an object, but just one method.

您要做的不是模拟而是间谍(部分模拟)。您不想模拟对象,而只想模拟一种方法。

This works:

这有效:

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;
    }
}

and

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"));
    }
}

But you should not use spy. You should refactor class into two, so that you can test one against a mock of the other.

但是你不应该使用间谍。您应该将类​​重构为两个,以便您可以针对另一个模拟测试一个。

回答by David M. Karr

You can't test code in Mocked classes. If you just Mock it, all of the methods are stubs.

你不能在 Mocked 类中测试代码。如果你只是 Mock 它,所有的方法都是存根。

You have to Spy it instead. Read the Mockito documentation on how to use Spy.

你必须监视它。阅读有关如何使用 Spy 的 Mockito 文档。