5

我在这里看过一个类似的问题,我想我知道人们的答案在哪里,但我需要确认是否应该为我的解决方案创建带有 Stubbed 存储库的纯单元测试。

如果我有以下单元测试(使用 Microsoft 的 Fake Assemblies 和 MSTest 创建):

 [TestMethod]
 public void creating_user_returns_a_valid_id()
 {
     var userId = new Random().Next(1, 1000);

     var userRepository = new StubIDataEntityRepository<User>
     {
         CreateT0 = x =>
             {
                 return userId;
             }
     };

     var user = new User();

     var result = userRepository.CreateT0(user);

     Assert.AreEqual(result, userId);
 }

现在,我一直在学习单元测试,我明白纯单元测试不能跨越任何边界或职责,因此是存根。我知道,如果我想测试在我的数据库中创建用户确实会变成有效的用户 ID,我需要创建一个集成测试。那么,究竟,我在这里测试什么呢?我知道人们说应用程序逻辑,这一切都非常有效,但我肯定正在创建一个创建 id 的测试,告诉假存储库从其 Create 方法返回该 Id,然后确认从 Create 方法返回的 Id 是相同的值. 感觉就像我为以下内容做了很多工作:

x = 1, y = 1, assert.areequal(x,y)!!

答案真的是关于培训开发人员通过 TDD 设计他们的代码吗?如果你们中的任何一位 TDD 专家可以启发我,将不胜感激!

亲切的问候

4

3 回答 3

10

您没有在这里测试任何有用的东西。

每个单元测试都有一个所谓的被测系统(SUT)。这就是您要测试的课程。
要测试 SUT,您不能模拟它,因为您将测试模拟,而不是 SUT。这有点毫无意义。

在您的情况下,您似乎想要测试存储库,但您也在模拟存储库,使测试毫无意义。

您想在 SUT 是另一个使用该存储库的类的测试中使用模拟存储

测试存储库很可能是集成测试的任务。无法使用单元测试来测试直接访问数据库的存储库方法。

于 2013-01-07T15:53:43.840 回答
3

通过“模拟”或“存根”您的数据访问,您可以确保您的单元测试评估代码的性能。使用模拟,您可以准确地知道调用时将返回什么数据,以及它应该采用什么格式。您可能不是唯一一个写入数据库或数据文件的人,因此您的测试结果可能会发生微妙的变化,让您摸不着头脑。

在流程工业中,这个概念被称为隔离测试,它可以更好地了解(恕我直言)在单元测试中试图实现的目标。当你刚刚开始一个项目时,你所说的“做大量工作”是有效的,但项目复杂性是一种熵:它只会随着你运行的时间越长而变得更糟。尽早进入良好的实践可能会为您节省一些进一步的调试噩梦。

希望有帮助:)

于 2013-01-07T15:53:07.770 回答
0

这个问题做得非常好。我的回答是,如果你的鼻子闻到可疑的东西,那可能是。

如果您的应用程序与数据库接口,您应该将数据库访问权限委派给角色(通常称为 XXXRepository),其中 XXX 是被持久化的资源类型(例如客户)。

  • 现在,如果您想测试 XXXRepository 的实现,您应该编写集成测试(即验证应用程序的其余部分是否与 DB 子系统集成的测试)。换句话说,是否正在满足合同(XXXRepository)的条款。因此称为“合同测试”。
  • 如果您在“应用程序的其余部分”部分测试代码,则出于隔离和速度的原因,您应该编写单元测试并模拟 XXXRepository 角色。

简而言之,如果您的 SUT 负责写入文件 - 您的测试应该调用 SUT 方法并验证文件是否相应更改。还有什么……我们只是为以后的惊喜做准备。

于 2013-01-08T06:30:48.340 回答