当前位置: 首页 > 知识库问答 >
问题:

使用Mockito模拟内部方法

冯和硕
2023-03-14

我是莫基托的新手。我试图通过模拟数据库交互为服务编写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调用而不是模拟调用。

共有2个答案

沈枫涟
2023-03-14

如果您不能更改TestService类(遗留代码),可以用PowerMockito(https://github . com/jayway/powermock)模拟新实例。它使用自己的junit runner (PowerMockRunner ),允许字节码操作。

以下是您的代码示例:

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
public class TestServiceTest {

   @Mock
   TestDAO testDaoMock;

   @Test
   public void test() throws Exception {
    List<String> testlist = new ArrayList<>();
    testlist.add("test1");
    when(testDaoMock.getListfromDB(anyString())).thenReturn(testlist);
    PowerMockito.whenNew(TestDAO.class).withAnyArguments().thenReturn(testDaoMock);
    TestService testService = new TestService();
    Response actualResponse = testService.getTestList("testType");
    assertEquals(expectedResponse, actualResponse);
    }
}

您需要将powermock-api-mockito和powermock-module-junit4添加到您的依赖项中。

居星阑
2023-03-14

您的问题在于以下陈述:

TestDAO testdao = new Testdao(sqlconn);

您从 mock() 获得的测试道实例不是测试道中使用的实例

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

[更新]

如果不能选择适当的IOC,您可以引入一种分配DAO的方法,然后spy()它。该方法必须是包私有的。这在这里描述。

另一个选项是添加一个包私有构造函数,将<code>testdao

 类似资料:
  • 使用mockito模拟一个方法会确保永远不会调用被模拟的方法吗?我有一个主类,它包含一些我想为其编写单元测试的代码,还有一个单元测试类MainTest,它包含主类的单元测试。 eg: 源类: JUnit测试(使用mockito) 这项测试失败了。为什么?

  • 我一直认为Mockito工作某种代理之类的东西。但现在我发现,Mockito允许我做一些像 这不适用于代理。它是如何做到这一点的?这种技术可以用来调用内部AOP方法吗?(请参见Spring AOP不适用于另一个方法中的方法调用)

  • 我有一个类需要测试。以下是的定义: 并根据值从数据库中检索一些要操作的数据。对于该数据库,值通过JSON文件持久化。 这使事情复杂化了。我需要的是在测试时将其设置为某个特定的日期。有没有办法可以用mockito模拟局部变量的值?

  • 我的测试存根是 我在这里做错了什么?

  • 问题内容: 我对模拟还很陌生,并且我一直在尝试模拟实际内容(本质上仅在内存中创建一个虚拟文件),以便在任何时候都不会将任何数据写入磁盘。 我尝试过模拟文件和模拟尽可能多的属性的解决方案,然后还使用文件写入器/缓冲写入器将其写入,但是这些方法不能很好地工作,因为它们需要规范路径。有人找到了除此以外的解决方案,但我正在解决这个错误? 我一直在这样做: 任何想法或指导都将非常有帮助。在此之后的某个地方,

  • 问题内容: 我有四个让我们说A,B,C,D的类,每个类都从另一个调用方法。 现在我已经模拟了类A,并且想模拟使用嘲笑的方法 并希望在递归方法调用上获取“ foo” 应该回来 我试过了 when(a.getB()。getC()。getD())。thenReturn(“ foo”); 但是得到了nullPointerException 然后我尝试 doReturn(“ foo”)。when(a.get