为我的 DAO 编写测试用例的最佳 TDD 方法是什么?

What is the best TDD approach for writing a test case for my DAO?

我现在很难编写一些测试用例,因为我是 TDD 的新手。比如我有这个dao方法,

public Customer getById(Long id) {
    if (id < 1L) {
        return null;
    }
    MapSqlParameterSource params = new MapSqlParameterSource("id", id);

    return jdbcTemplate.queryForObject("select * from customer where id = :id", params, new RowMapper<Customer>() {

        public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
            return createCustomerFromResultSet(rs);
        }
    });
} 

我希望对其进行负面测试。负测试用例,

@Test
public void getByIdNegative() throws Exception {
    Customer customer = customerDao.getById(-1L);
    log.debug("Customer retrieved: " + customer);
    assertNull(customer);
}

抛出异常,所以我在dao方法中写了上面看到的if子句来解决它,但似乎这不是正确的方法。我应该期待例外吗?处理它?如果是这样,在哪一层以及如何?在这种情况下,负面测试是否必要或只是矫枉过正?这些是我现在想到的一些问题。我想知道如何按照正确的 TDD 原则干净地处理这个测试用例。

恕我直言,好的方法是从为您的方法编写 javadoc 开始。那就是它的规格。

它必须说明方法的作用,returns 和抛出。

queryForObject() 指定如果查询没有恰好 return 一行,则抛出 IncorrectResultSizeDataAccessException

您的方法也应该处理数据库中不存在 ID 的情况。它可以抛出相同的异常,或者抛出另一个异常,或者 return null,或者 return 一个空的 Optional<Customer> 而不是 Customer。那是的设计选择。

做出选择后,将其记录下来,并编写验证此合同的测试:

  1. 当获取数据库中存在的客户时,检查该方法确实 return 是该客户
  2. 当获取数据库中不存在的客户时,检查该方法是否抛出正确的异常,或者 return 是否正确的值,具体取决于您的设计选择。

显然用-1 测试,并为这个特定的标识符添加一个特例是错误的。因为 -1 只是数据库中不存在的大量 ID 之一。该方法不能使测试通过。该方法必须按照其规范中的说明进行操作。