当前位置: 首页 > 知识库问答 >
问题:

集成测试共享数据库的多个实体框架DBContext

苏坚成
2023-03-14
public class Context1 : DbContext {
    public Context1()
        : base("DemoDb") {
    }
}

public class Context2 : DbContext {
    public Context2()
        : base("DemoDb") {
    }
}

所有数据库更新都是通过脚本完成的,不依赖于迁移(也不会继续)。问题是-如何针对这些上下文进行集成测试?

我相信这里有三个选项(可能还有更多我只是不知道而已)

选项1-超级上下文-包含设置数据库所需的所有模型和配置的上下文:

public class SuperContext : DbContext
{
    public SuperContext()
        : base("DemoDb") {
    }
}

在此选项中,测试数据库将根据超级上下文设置,所有后续测试将通过较小的上下文完成。我不喜欢这个选项的原因是我将复制我已经构建的所有配置和实体模型。

选项2-为集成测试创建一个自定义初始化器,它将运行所有适当的db初始化脚本:

public class IntegrationTestInitializer : IDatabaseInitializer<DbContext> {

    public void InitializeDatabase(DbContext context) {
        /* run scripts to set up database here */
    }
}

此选项允许针对真实的数据库结构进行测试,但也需要在每次添加新的db脚本时进行更新

选项3-仅测试单个上下文:

在此选项中,只需让EF根据上下文创建测试数据库,所有测试都将在其自身的“沙箱”中操作。我不喜欢这样做的原因是,这感觉不像是在对数据库的真实表示进行测试。

我目前倾向于选择2。你们都怎么想?有更好的方法吗?

共有1个答案

西门安民
2023-03-14

我经常使用集成测试,因为我仍然认为当涉及到依赖于数据的过程时,集成测试是最可靠的测试方式。我也有几个不同的上下文和数据库升级的DDL脚本,所以我们的情况非常相似。

我最终得到的是选项4:通过常规用户界面维护单元测试数据库内容。当然,大多数集成测试都是临时修改数据库内容的,这是测试“Act”阶段的一部分(稍后将详细介绍此“临时”),但在测试会话开始时不会设置内容。

原因就在这里。

集成测试,就像单元测试一样,应该是可以独立执行的。它们不应依赖于其他测试,也不应受其影响。我假设您的问题的背景是您为每个集成测试创建并种子化一个数据库。这是实现独立测试的一种方法。

但如果只有一个数据库,而没有种子脚本,该怎么办?您可以为每个测试还原一个备份。我们选择了一种不同的方法。每个集成测试都在从未提交的transactionscope中运行。实现这一点是非常容易的。每个测试fixture都继承自一个具有以下方法(NUnit)的基类:

[SetUp]
public void InitTestEnvironment()
{
    SetupTeardown.PerTestSetup();
}

[TearDown]
public void CleanTestEnvironment()
{
    SetupTeardown.PerTestTearDown();
}

SetupTearDown中:

public static void PerTestSetup()
{
    _tranactionScope = new TransactionScope();
}

public static void PerTestTearDown()
{
    if (_tranactionScope != null)
    {
        _tranactionScope.Dispose(); // Rollback any changes made in a test.
        _tranactionScope = null;
    }
}
 类似资料:
  • 我曾想过简单地对数据库运行一个小命令并捕获任何异常,然而,如果出现问题(例如app.config丢失或数据库服务器关闭),应用程序将花费大量时间运行此代码,然后抛出异常(大约1分钟)。我想这是由于连接超时等,但我已经摆弄了这样的属性没有任何作用。 有没有人能提供任何关于去哪里的建议?

  • 我可以有一个包含Springboot集成测试的罐子吗

  • 我有一个带有“Status”布尔值的付款模型,该布尔值默认为false。付款后,我需要将特定付款的“状态”更新为true。 这是我一直试图用来更改特定数据库条目的代码,但它并没有改变它。我做错了什么? 谢谢 这就是最终起作用的原因:

  • 场景: 我有两个MySQL数据库: 大型主数据库 小型客户端数据库 示例表: 大数据库用户: 文本用户名 int id varchar登录 varchar密码 ...更多的领域 客户端数据库用户 内部id int UNIQUE api\u id(来自master的id) varchar登录 varchar密码 问题:我需要同步数据库,但我不知道如何以最佳方式进行同步。我读过这个问题,但它很老了,没

  • 问题内容: 在这些多重性冲突中,我所看到的大多数其他问题都是代码优先的,而我将DB作为第一位。我进行了一些模式更改,并且从数据库刷新模型时出现以下错误: 多重性与关系“ FK_MarketSelectionWager_Bet”中的角色“赌注”中的引用约束冲突。由于从属角色中的所有属性都是不可为空的,因此,主体角色的多重性必须为“ 1”。 我需要在SQL或模型中进行修复的任何指针都很棒。 以下是涉及

  • 我有两个django REST API项目,我将它们解耦为微服务架构,其中一个服务是(SSO),它处理身份验证(我使用的是基于JWT令牌的身份验证)并管理用户信息,另一个是工资单服务。 问题是与工资单服务中的某个模型有关系。具体来说,我在工资单服务中有一个类,它有一个字段。这是我将添加用户的地方,我将从查询SSO服务中获得。 考虑到每个服务都有自己的数据库,我如何跨微服务共享数据库。