不是嘲弄方法,而是调用原始方法(mockito)

时间:2018-02-05 13:58:53

标签: java unit-testing junit mockito

这门课我想测试..

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

}

这是单元测试用例......

@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);

    }
}

当我运行这个测试用例时,它调用checkNumbers类的原始方法而不是调用mock。我通过将Sysout放入checkNumbers.check()方法来了解这一点。

任何人都可以突出显示,我在做错误。

2 个答案:

答案 0 :(得分:1)

checkNumbers内部 add方法创建

checkNumbers checkobj=new checkNumbers();

Mockito注入功能(@InjectMocks)无法为您填充此内容。

为了让Mockito将checkNumbers设置为模拟,您需要允许它被注入。

例如:将其移出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;
    }
}

@InjectMocks注释的指示下,Mockito会尝试按照(按此顺序)之一注入模拟:

  1. 构造函数注入
  2. Setter injection
  3. 物业注入
  4. 如果您宣布checkNumbers为班级成员,那么Mockito将按照上述#3注入。或者,你可以像这样声明一个构造函数......

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

    ...... Mockito将按照上面的#1注入模拟实例。

    这样可以使您的类明确显示构建时所需的任何其他类,并且可以允许您交换checkNumbers的不同实现,从而促进不同的组合AddNumbers的形式。

    更多详情in the Mockito docs

答案 1 :(得分:0)

@glytching的上一个答案绝对正确。

以下是使用重写getter方法的其他可能解决方案。

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

你的测试已经覆盖了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);
    }
}

关于您的代码的一般性评论:

  • 以大写字母命名一个类:CheckNumbers
  • 按姓名命名变量:flg - > flag
  • if(flg == true)可简化为if(flg)
  • if/esle构造可以简化为一行解决方案:return flag ? a + b : 0
  • 避免使用测试名称中的幻数:testAdd1 - > addShouldSumTwoGivenIntegers()