【问题标题】:Right way to Unit-test Repository.Update Method单元测试 Repository.Update 方法的正确方法
【发布时间】:2018-12-06 15:24:35
【问题描述】:

假设我们有典型的存储库

 public class Repository:IRepository<Entity>
    {
            public Entity GetById(int id)
            {
                //blah
            }

            public IEnumerable<Entity> All()
            {
                //blah
            }

            public void Insert(Entity entity)
            {

            }

            public void Update(Entity entity)
            {
                //blah
            }

            public void Delete(Entity entity)
            {
                //blah
            }
    }

使用 MSTest,我想测试存储库插入和更新实体的能力。只要它是具体的存储库,我就会针对真实的数据库进行测试。

所以,当我测试 Insert 方法时 - 策略很明确

  1. 创建新实体
  2. 保存
  3. 按 id 获取实体
  4. 存储库返回断言实体

但是当我想到更新方法测试时,这一切都变得有些棘手。 主要问题是

  • 如何确保 DB 已经存储了对象,我可以获取并尝试 更新?
  • 如何针对空数据库测试更新?

看起来解决方法需要一些不必要的代码,并且测试会变得臃肿。 有什么好办法吗?

【问题讨论】:

  • 您的意图是“单元测试”并不是真正的单元测试,因为您不是在测试一个孤立的单元,而是测试多个单元的集成。重新考虑你想做什么。如果你想对你的代码进行单元测试,那么只测试更新方法。您可以通过测试更新方法是否遵循预期路径并将其实例保持在预期状态来做到这一点。
  • 单元测试我处理 RDBMS 的 Repository 类的正确方法是什么?不知何故,我需要检查它应该做的事情。
  • 尝试以这种方式查看:您想对更新方法进行单元测试。如果数据库失败(例如磁盘空间已满),这并不意味着您的更新方法错误或损坏。您无需测试您的项目是否已在数据库中更新。您需要检查您的更新方法是否符合您的预期。 (例如,正确调用数据库层)
  • 对我来说有点争议。您试图告诉所有针对真实数据库的测试都不好?还是不是“单位”?同意最好将其称为“集成测试”,但不同意它不合适。在你的例子中,我更愿意看到这样的测试出了问题。
  • 正如@Polity 所说,它们不是“单元测试”,但要回答您的问题,它们还不错,存在差异,一个并不否定另一个的需要。我根本不知道您使用的是什么 ORM,但是如果您将任何内容注入到 Repository 类中,则可以测试当您在存储库上调用 update 时使用正确的参数调用正确的方法。这是一个单元测试,因为您只测试存储库,没有别的。集成测试是您尝试实现的目标,并测试您是否正确映射到数据库。

标签: c# unit-testing repository mstest


【解决方案1】:

使用ClassInitializeTestInitialize,以及ClassCleanupTestCleanup 使用已知实体预填充数据库。然后针对它们运行 Update() 测试。

不确定如何解释“不必要的代码”...看起来您将不得不做一些事情来填充您的数据库以测试 Update() 方法;至少使用上面列出的属性可以让您实现初始化和清理数据库所需的逻辑,而不会污染实际的测试方法。

【讨论】:

  • 不同的Test方法可以有不同的TestInitialize方法吗?
  • 否;它们是特定于类的。不过,您可以将测试分成不同的类。
猜你喜欢
  • 2016-03-25
  • 2022-01-14
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 2015-12-15
相关资源
最近更新 更多