【问题标题】:Unit testing async database methods单元测试异步数据库方法
【发布时间】:2015-03-09 04:37:48
【问题描述】:

我有一个想要使用 MS Test 测试的 Web API。我想特别测试一个控制器。这是初始化代码:

public class MyControllerTests
{
    private static MyController controller;

    [AssemblyInitialize]
    public static void Initialize(TestContext context)
    {
        controller = new MyController();

        IoC.Register(Component.For<IDbContextFactory>().ImplementedBy<MockDbContextFactory>());
        // other config
    }
    // test methods, all async
}

这是模拟上下文工厂。是否在所有 API 方法中都使用它来获取数据库上下文。

public class MockDbContextFactory : IDbContextFactory
{
    MyContext context;

    public MyBaseContext GetContext()
    {
        if (context == null)
        {
            context = new MyContext(new DropCreateDatabaseAlways<MyContext>());

            //populate with mock data...
        }

        return context;
    }
}

在我为 delete 方法添加测试之前,一切都很好。它在其他方法之前完成,因此它从共享上下文中删除对象并且其他测试失败。不,我有两个想法:每个方法的新上下文(使用 [TestInitialize] 重置器),但是底层数据库仍然相同,并且在插入新的模拟对象时我遇到了很多关键冲突。另一个想法是在内存中设置一个新数据库并拥有完全独立的实例。我找到了Effort,但我认为这是一种矫枉过正的做法,而且我的做法是错误的。

我使用 Castle Windsor 作为 IoC 容器,以防万一有办法在 IoC 级别上做到这一点。

【问题讨论】:

  • 巧合的是,我最近写了一篇关于使用 Effort 对您的 DbContext 进行单元测试的博文。如果你决定走那条路,你可能会发现它很有趣(实际上,它很容易设置):vannevel.net/blog/2015/02/26/11
  • 旁注:您的帖子中没有任何内容需要/谈论异步等待...看起来您正在谈论缺乏隐式测试排序(这是一件好事)-您会从同步调用中获得相同的失败......最好将“异步”编辑掉。

标签: c# entity-framework unit-testing async-await mstest


【解决方案1】:

我认为您可能以错误的方式看待这个问题。

单元测试的目的是测试与任何其他单元隔离的功能单元。无需对实体框架进行单元测试,它已经过彻底测试。每当您创建 CRUD 操作的测试时,您实际上是在创建集成测试,而不是单元测试。

如果您确实需要测试您的 CRUD 操作,那么您的模拟工厂应该只是为传递给它的所有操作返回成功,或者在本地保存数据以传回以进行验证。它不应该创建一个“测试” DbContext 对象,该对象不仅要与数据库交互,还要与其他测试交互。您的单元测试应该只专注于验证被测函数中的操作。

现在,如果您的意图是执行集成测试,那么通常的做法是让测试本身插入要删除的对象。让删除测试尝试删除由另一个测试插入的记录总是对时间构成挑战。另外,使用DropCreateDatabaseAlways,甚至无需担心删除插入测试插入的对象。

【讨论】:

  • 在删除测试中创建要删除的对象似乎如此明显,我不敢相信我没有想到这一点。
猜你喜欢
  • 2020-07-14
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 2021-09-19
  • 2016-05-08
  • 2017-12-21
  • 2014-08-21
  • 1970-01-01
相关资源
最近更新 更多