【问题标题】:Unit testing of DAO classes using JUnit and Mockito使用 JUnit 和 Mockito 对 DAO 类进行单元测试
【发布时间】:2020-01-17 17:40:43
【问题描述】:

我有 DaoImpl 类:

public class MessageTypeDaoImpl implements MessageTypeDao{

    public int[] createMessageTypes(final List<MessageType> messageTypes){
        String sql = "INSERT INTO MSG_TYPE VALUES(?, ?)";
        return jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                MessageType messageType = messageTypes.get(i);
                ps.setString(1, messageType.getMessageId());
                ps.setString(2, messageType.getMessageName());
            }

            public int getBatchSize(){
                return messageTypes.size();
            }
    });
}

我的测试:

@RunWith(MockitoJUnitRunner.class)
public class MessageTypeDaoImplTest {

@Mock
private JdbcTemplate jdbcTemplate;

@Spy
@InjectMocks
MessageTypeDaoImpl messageTypeDaoImpl;
@Before
public void setUp(){
    MockitoAnnotations.initMocks(this);
}
@Test
public void createMessageTypes() {
    int[] returnCount = new int[1];
    List<MessageType> messageTypeList = new ArrayList<MessageType>();
    messageTypeList.add(getSampleMessageType());
    messageTypeDaoImpl.createMessageTypes(messageTypeList);
    doReturn(returnCount).when(messageTypeDaoImpl).createMessageTypes(messageTypeList);
    assertEquals(returnCount, messageTypeDaoImpl.createMessageTypes(messageTypeList));
}
}

public MessageType getSampleMessageType(){
    return new MessageType("messageTypeId", "messageTypeName");
}

测试成功,但是当我运行 junit 覆盖测试时,它显示 public void setValues() 方法没有被覆盖,因此我的整体单元测试行覆盖率低于要求。我们可以涵盖那部分吗?如果是,那么我们如何做到这一点?谢谢。

【问题讨论】:

  • 不要模拟 JdbcTemplate,使用真实的实例。您的 Spring 容器中可能已经有一个真实的实例。请注意,JdbcTemplate 具有依赖关系,例如:DataSource。您可能需要模拟 DataSource 并将其注入 JdbcTemplate。您可以让 Spring 为您注入 if:在您的单元测试中有一个 DataSource 类型的成员变量,并在其上使用 @MockBean 注释。
  • 在 doReturn().when() 语句之前调用 `messageTypeDaoImpl.createMessageTypes(messageTypeList);` 有什么意义?还有:你为什么在这里使用间谍?似乎您正在将 Mockito 的各种元素拼凑在一起,却不知道它们的实际用途是什么?
  • @GhostCat 我调用了 createMessageTypes,因为如果我不这样做,该方法将不会被调用,并且不会有代码覆盖。我需要确保我的代码覆盖率尽可能高(IntelliJ IDE 中的类 % 和行 % 覆盖率)。关于 Spy 注释,我在调用方法时遇到了问题(再次用于代码覆盖),stackoverflow 上有人说我们可以使实例接近真实实例(或半模拟)并调用该方法。我之前没有做过那么多的单元测试,更不用说mockito了。所以我想了解如何让它协同工作。

标签: java unit-testing mockito junit4 dao


【解决方案1】:

试试下面的代码spinet。我也会介绍代码。我从头到尾检查了它,它起作用了。

int[] batchInsert=new int[] {1,2};
        try {

            Mockito.doAnswer(invocationOnMock -> {

                PreparedStatement ps = Mockito.mock(PreparedStatement.class);
                BatchPreparedStatementSetter psr = invocationOnMock.getArgument(1);
                psr.setValues(ps, 1);
                return batchInsert;

            }).when(jdbcTemplate).batchUpdate(anyString(),  Mockito.any(BatchPreparedStatementSetter.class));

【讨论】:

    猜你喜欢
    • 2021-03-15
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 2018-12-03
    相关资源
    最近更新 更多