我是单元测试中模拟事物的新手,我已经开始尝试使用Mockito。使用Mockito可以执行以下操作吗?
我正在尝试为分层 Web 服务应用程序编写单元测试。此时,我正在测试服务层,它调用 DAO 层从数据库中获取数据。 我需要模拟数据库结果,这样我就不会在每次运行单元测试时对数据库进行真正的更新调用。
我正在考虑通过模拟我的服务层调用的 DAO 对象来做到这一点,但我需要在不更改源代码的情况下做到这一点。如果我目前正在对服务层进行单元测试,如何使其使用模拟的 DAO 层?
我的单元测试如下所示:
@Test
public void testUpdate() {
RequestObject request = new RequestObject();
request.setEntityId(1234);
request.setLob('testLOB');
ResponseObject response = service.updateMember(request);
}
我的服务方式:
public ResponseObject updateMember(RequestObject request) {
ResponseObject result = DAO.updateMember(request);
}
在这种情况下,是否可以在不嘲笑服务的情况下模拟 DAO? 编辑:我正在使用Maven进行依赖管理。
你需要在测试的设置中使用像Mokito这样的嘲笑者。像这样:
public class YouTestClass {
@MockBean
DAO mockedDAO;
...
@Test
public void testUpdate() {
Mockito.when(mockedDAO.updateMember(Mockito.isA(RequestObject.class)).thenReturn(new ResponseObject());
RequestObject request = new RequestObject();
request.setEntityId(1234);
request.setLob('testLOB');
ResponseObject response = service.updateMember(request);
}
您需要将.thenReturn(new ResponseObject());
调整为您实际希望接收的测试响应对象。此外,您的 DAO 类似乎是一个静态类,因此如果可能的话,您可能需要阅读如何模拟它。否则,您可能希望将其设置为单例。
例如,如果您在服务层上进行测试,则可以执行以下操作。
@Mock
private DAO dao;
@Test
public void testUpdate() {
RequestObject request = new RequestObject();
request.setEntityId(1234);
request.setLob('testLOB');
ResponseObject result = //the response that you want
when(dao.updateMember(eq(request))).thenReturn(result);
ResponseObject response = service.updateMember(request);
// ASSERTIONS HERE
}
我所做的基本上是:例如,当我通过服务调用调用 DAO 时 '''when(AccountManagerImpl.saveAccount(testAccount((.thenReturn(mockedAccount('''. 挑战在于该方法返回 void 时,即只是将一些数据转储到表中。这意味着您必须间接确认方法调用。就我而言,我使用"verify(mockedAccount, times(1((.saveAccount("。 这只能保证该方法至少被调用过一次。当然还有更深的层次。如果您想确认数据已写入实际表,那么您自然需要一个更强大的测试工具,即设置测试数据库等。或者你可以做更便宜的[可以说是较少约束的]替代方案,例如简单地模拟结果集 when(mockPreparedStmnt.execute(((.thenReturn(Boolean.TRUE( 这当然会做出大量的假设,这些假设可能会回来咬你。你基本上是在说 - 让我们假设数据被正确保存。但是,如果这个假设本身就是SUT呢?我只是在代码审查期间提出它 - 在这里,测试覆盖矩阵将为您节省许多夜晚。