使用Mockito模拟内部方法

时间:2016-08-15 18:38:09

标签: java junit mockito

我是Mockito的新手。 我试图通过模拟数据库交互来编写服务的jnuit:

我有以下课程(仅代表实际课程)

public class TestService{

    public Response getTestList(String type){
        list = getListbyType(type);

        return response.entity(list);
    }

    private List getListbyType(String type){
          ...
          ..
          TestDAO testdao = new Testdao(sqlconn);
          list = testdao.getListfromDB(type)
          return list;
   }
}

我的测试类就像

public class TestServiceTest{

    @InjectMocks
    private TestService testService = new TestService();
    @Test
    public void getTestListTest(){

        List testlist = new List();
        tetslist.add("test1");

        TestDAO testdaomock = mock(TestDAO);
        when(testdaomock.getListfromDB("test")).thenreturn(list);

        list = testService.getTestList(test);
    }
}

但是当我运行这个测试时,它仍然会调用实际的DB调用并从db中检索值,而不是模拟的值,我应该模拟sql连接和非默认构造函数吗?我很无能。

- 更新

正如人们所建议的,我将DAO实例化移动到我的服务构造函数并且还使用了Spy,但仍然调用了我的实际DB调用而不是模拟调用。

1 个答案:

答案 0 :(得分:2)

您的问题出在以下声明中:

TestDAO testdao = new Testdao(sqlconn);

您从mock()获得的TestDAO实例不是testdao.getListfromDB(type)之后的new中使用的实例

为了成功模拟,您需要始终应用依赖项的反转。这意味着new必须只显示在您不打算测试的类中,例如简单的工厂或Spring配置文件。

[更新]

如果没有合适的IOC,您可以引入一个分配DAO然后spy()的方法。该方法必须是包私有的。这被描述为here

另一种选择是添加一个包含私有构造函数的{ - 1}}作为参数,并在该构造函数的术语中表示默认构造函数。