【发布时间】:2019-05-26 17:33:17
【问题描述】:
我似乎有一个奇怪的并发问题,我似乎无法解决。 当我构建 DbContext 的实现时,我注入了我想由模型构建器构建的实体(不用担心为什么)。这仅由我的应用在运行时完成一次并且运行良好,但是当我在集成测试数据库集成时,我只注入了我的 InMemoryDatabase 所需的测试实体。
现在我似乎遇到了一个奇怪的问题,在需要不同实体的不同类文件中的两个单元测试似乎被交叉了。
我继续运行单元测试,第一个测试会通过,但第二个测试会失败,说模型中不存在 TestObjectB。当我检查模型时,它说 TestObjectA 存在,即使它没有在这个测试中注入。因此,好像 DataContext 的实现是静态的并被覆盖......这些是不同的文件和上下文的新构造函数,我不明白它们是如何交叉的?如果我运行自己失败的单元测试,它就会通过。
请注意,以下代码已针对您的视图进行了简化。
数据库上下文:
public class DataContext : DbContext
{
private readonly List<IEntity> _entities;
public DataContextA(List<IEntity> entities, DbContextOptions options) : base(options)
{
_entities = entities;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entity in _entities)
{
modelBuilder.Entity(entity.GetType());
}
}
}
测试实施 1:
[Fact]
public void CheckUniqueFieldA()
{
var options = new DbContextOptionsBuilder<DataContext>();
options.UseInMemoryDatabase(Guid.NewGuid().ToString());
using (var context = new DataContext(new List<IEntity> { new TestObjectA() }, options.Options))
{
//Do Something
}
}
测试实施2:
[Fact]
public void CheckUniqueFieldB()
{
var options = new DbContextOptionsBuilder<DataContext>();
options.UseInMemoryDatabase(Guid.NewGuid().ToString());
using (var context = new DataContext(new List<IEntity> { new TestObjectB() }, options.Options))
{
//Do Something
}
}
【问题讨论】:
-
尝试将两个类放在同一个测试集合中,这样它们就不会并行运行并相互影响。
-
嗨@AmanB,这将解决问题,但反对这一点。我不知道他们为什么会相互影响。他们不应该有任何导致他们相互影响的代码。知道为什么会这样吗?
-
见docs.microsoft.com/en-us/ef/core/modeling/dynamic-model。默认情况下,
OnModelCreating绑定到上下文 type,而不是上下文 instance。 -
@IvanStoev 非常感谢。我不知道“这是由 EF 使用的模型缓存机制引起的,它通过仅调用 OnModelCreating 一次并缓存模型来提高性能”如果你回答我会接受它。
标签: c# entity-framework-core xunit