简体   繁体   English

不是模拟方法,而是调用原始方法(mockito)

[英]Not mocking methods, instead calls original methods (mockito)

This class I want to test.. 我要测试的课程。

public class AddNumbers {

    public int add(int a, int b){

        checkNumbers checkobj=new checkNumbers();

        boolean flg = checkobj.check(a, b);

        if(flg == true){

            return a+b;
        }else{

            return 0;
        }
    }

}

Here is the unit test case... 这是单元测试用例...

@RunWith(MockitoJUnitRunner.class)
public class AddNumbersTest {

    @Mock
    checkNumbers checkobj;

    @InjectMocks
    AddNumbers addobj = new AddNumbers();


    @Test
    public void testAdd1(){

        int a=10;
        int b=5;

        Mockito.when(checkobj.check(a, b)).thenReturn(true);
        assertEquals(addobj.add(a,b),15);

    }
}

When I running this test case, it calls original method of checkNumbers class instead calling mocked one. 当我运行此测试用例时,它将调用checkNumbers类的原始方法,而不是调用checkNumbers方法。 I get to know this by putting Sysout in checkNumbers.check() method. 我通过将Sysout放在checkNumbers.check()方法中来了解这一点。

Can anyone highlight, where I m doing the mistake. 谁能强调我在哪里做错了。

checkNumbers is created inside the add method ... checkNumbers内部创建add的方法...

checkNumbers checkobj=new checkNumbers();

The Mockito injection feature ( @InjectMocks ) cannot populate this for you. Mockito注入功能( @InjectMocks )不能为您填充此功能。

In order for Mockito to set checkNumbers to a mock you'll need to allow it to be injected. 为了让Mockito将checkNumbers设置为模拟,您需要允许它被注入。

For example: move it out of add() and declare it as a class member: 例如:将其移出add()并将其声明为类成员:

private checkNumbers checkobj;

public int add(int a, int b){
    boolean flg = checkobj.check(a, b);

    if(flg == true){

        return a+b;
    }else{

        return 0;
    }
}

When instructed by the @InjectMocks annotation Mockito will try to inject mocks by one of (in this order): 当受到@InjectMocks批注的指示时,Mockito将尝试通过以下一种方式注入模拟:

  1. Constructor injection 构造器注入
  2. Setter injection 二传手注射
  3. Property injection 资产注入

If you declare checkNumbers as a class member then Mockito will inject is as per #3 above. 如果您将checkNumbers声明为类成员,则Mockito将按照上面的#3进行注入。 Alternatively, you could declare a constructor like so ... 另外,您可以像这样声明一个构造函数...

private checkNumbers checkobj;

public AddNumbers(checkNumbers checkobj) {
    this.checkobj = checkobj;
}

... and Mockito will inject the mock instance as per #1 above. ...,然后Mockito将按照上面的#1注入模拟实例。

This would have the benefit of making your class explicit about any other classes it needs at construction time and could allow you to swap in different implementations of checkNumbers thereby facilitating the composition of different forms of AddNumbers . 这将具有使您的类在构造时明确需要的任何其他类的好处,并且可以允许您交换checkNumbers不同实现,从而有助于组成不同形式的AddNumbers

More details in the Mockito docs . 在Mockito文档中有更多详细信息。

The previous answer of @glytching is absolutely correct. @glytching的先前答案是绝对正确的。

Here is other possible solution with overridden getter method. 这是覆盖吸气方法的其他可能解决方案。

public class AddNumbers {
    // This is new method to return a new instance of checkNumbers.
    checkNumbers getCheckNumbers() {
        return new checkNumbers();
    }

    public int add(int a, int b){
        checkNumbers checkobj = getCheckNumbers();
        // do what you need
    }
}

You test has overridden getCheckNumbers(): 您测试覆盖了getCheckNumbers():

@RunWith(MockitoJUnitRunner.class)
public class AddNumbersTest {
    @Mock
    checkNumbers checkobj;

    @InjectMocks
    AddNumbers addobj = new AddNumbers() {
        @Override
        checkNumbers getCheckNumbers() {
            return checkobj;
        }
    };


    @Test
    public void testAdd1(){
        int a=10;
        int b=5;

        Mockito.when(checkobj.check(a, b)).thenReturn(true);
        assertEquals(addobj.add(a,b),15);
    }
}

Couple general remarks regarding your code: 关于您的代码的一般说明:

  • Name a class starting by capital letter: CheckNumbers . 用大写字母开头的类命名为CheckNumbers
  • Name variables by full names: flg -> flag . 用全名命名变量: flg > flag
  • if(flg == true) can be simplified to if(flg) if(flg == true)可以简化为if(flg)
  • if/esle construction can be simplified to one line solution: return flag ? a + b : 0 if/esle构造可以简化为一种解决方案: return flag ? a + b : 0 return flag ? a + b : 0
  • Avoid magic numbers in test names: testAdd1 -> addShouldSumTwoGivenIntegers() . 避免在测试名称中使用幻数: testAdd1 > addShouldSumTwoGivenIntegers()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM