2

我正在寻找使用 jUnit 测试 DAO 类的最佳实践。我的 DAO 类有几个典型的 DAO 方法,例如 createUser(User user)、deleteUser(Long id)、updateUser(User user)、findUserById(Long id)...

所以 createUser 可能很简单,我可以创建一个用户,然后检查它是否有一个 id。如果是,则测试将通过。或者您更愿意创建一个用户,然后从数据库中读取用户并检查它是否 1) 找到用户 2) 返回用户的实例变量与之前保存的用户相同

那么 deleteUser 函数呢?它需要一个 ID,但为了获得 ID,我首先必须创建一个用户。那么如何做到这一点呢?使用测试方法中的 testCreateUser 方法还是 DAO 类中的 createUser 方法?

与 updateUser(User user) 相同,我需要先更新用户,而 findUserById(Long id) 我需要先更新 Id。

我认为我的要求很常见,所以我想知道是否有类似设计模式用于使用 jUnit 测试 DAO。

谢谢,保罗

4

4 回答 4

2

恕我直言,没有这样的设计模式来进行 JUnit 测试。您必须参考一些最佳实践。

例如,在以下情况下,您在删除之前不使用 testCreateUser 方法创建用户。为此,您必须使用 DAO 类。每个测试用例方法都是相互独立的。

那么 deleteUser 函数呢?它需要一个 ID,但为了获得 ID,我首先必须创建一个用户。那么如何做到这一点呢?使用测试方法中的 testCreateUser 方法还是 DAO 类中的 createUser 方法?

现在,要解决您的问题,您可以使用 setUp 和 tearDown 方法。在 setUp 方法中,您可以创建要测试的模拟对象,在 tearDown 中您可以删除它们。如果你这样做,每个测试方法都将获得相同的模拟数据集,你可以在这些数据上进行测试。

于 2012-10-09T14:42:12.690 回答
1

我通常的方法是在同一个测试中使用 DAO 的其他方法。例如

user = UserStore.create(...);
id = user.id();
loadedUser = UserStore.load(id);
assertThat(loadedUser, eq(user));

如果您采用这种方法,单元测试中的“单元”就是整个类,而您通常一次对一个函数进行单元测试。这是可以接受的,并且会产生经过良好测试的课程。这种方法的问题是,失败的测试可能是由于 UserStore.create 或 UserStore.load 中的错误,但我发现对于小类,调试起来并不难,而且往往工作得很好。我尝试了其他方法,在测试后手动检查数据库,但我发现额外的工作通常不值得。

一些框架,如 Rails,采用不同的方法。它们为您提供了一种在测试运行之前用数据播种数据库的方法。这很好用,因为框架使它变得容易。随着越来越多的工具为这种方法提供支持,也许这将成为常态。

于 2012-10-09T14:28:24.900 回答
1

IMO 单元测试应该能够自行运行。

因此,例如,删除测试将首先创建一个用户,然后将其删除并检查它是否不再存在(通过尝试加载它)。

依赖之前的测试不是一个好方法,因为如果之前的测试由于任何原因失败,下一个测试也会失败。

于 2012-10-09T14:37:02.193 回答
1

您可以使用内存数据库,该数据库在每次测试之前填充您的测试数据,并在测试执行完成后被丢弃。看看德比

要考虑的另一件事是,你真的应该对你的 DAO 层进行单元测试吗?Dao 的定义不应该包含业务逻辑,您最终会测试持久性框架。

于 2012-10-09T20:39:43.247 回答