gpt4 book ai didi

c# - 一次运行所有测试会导致其中一些测试失败,但是当它们被单独触发时,它们就可以正常工作

转载 作者:太空宇宙 更新时间:2023-11-03 20:49:34 26 4
gpt4 key购买 nike

我有一些奇怪的问题,每当我 Run all 时,我的一些测试都会失败。测试,但是当我一个接一个地启动它们时,一切正常

这是播种失败的代码 InMemoryDatabase

它必须添加一些 Permission s 至 Permissions表,然后创建 Group与权限有多对多关系的 s

基本上一个组可以有多个权限,一个权限可以在多个组中使用

但问题是

.Single抛出

Sequence contains more than one element

当所有测试同时运行,但单独运行时一切正常

有什么想法吗?

public class Tests : IDisposable
{
private readonly Context _context;

public void Dispose()
{
_context.Database.EnsureDeleted();
}

public Tests()
{
var o = new DbContextOptionsBuilder<Context>();
o.UseInMemoryDatabase("testDb");
_context = new Context(o.Options);
_context.Database.EnsureDeleted();
_context.Database.EnsureCreated();
}

[Fact]

public async void myTest()
{
Initializer.InitializePermissions(_context);
Initializer.InitializeGroups(_context);
(...)
}
}

public static class Initializer
{
public static void InitializePermissions(Context context)
{
var permissionNames = new List<string>
{
"CanCreateNewProduct",
"CanRemoveProduct",
};

foreach (var permission in permissionNames)
{
context.Permissions.Add(new Permission(permission));
}

context.SaveChanges();
}

public static void InitializeGroups(Context context)
{
var groups = new Dictionary<string, List<string>>();

groups.add("Admin", new List<string>{"CanRemoveProduct"};

foreach (var group in groups)
{
foreach (var permissionName in group.Value)
{
var permission = context.Permissions.Single(x => x.Name == permissionName);

group.GroupPermissions.Add
(
new Many2Many
{
Group = group,
GroupId = group.Id,
Permission = permission,
PermissionId = permission.Id
}
);
}

context.Groups.Add(new Group(group.Key, permissions);
}

context.SaveChanges();
}
}

最佳答案

这里的问题是您的测试正在使用共享状态。

(顺便说一句,如果你想知道为什么很多程序员会竭尽全力避免使用任何static并且你觉得他们的对象,依赖注入(inject)等过于复杂,当他们可以只是“让它静态”......这就是原因。)

您的Initializer可以可能保持静态,只要它不在内部维护状态。至少乍一看似乎不是,因为您将数据库上下文的实例传递给它。但是当您继续在您的系统中工作时,重要的是要保持这个初始化器在测试中不保持任何状态。

然后这将我们带到内存数据库本身:

o.UseInMemoryDatabase("testDb");

这些可以在整个应用程序中全局访问。 但是您可以为它们指定唯一的名称。例如:

var dbName = Guid.NewGuid().ToString();
o.UseInMemoryDatabase(dbName);

有了这个,每个数据库上下文都应该有一个唯一的数据库,您以后可以在任何可能需要的地方使用 dbName 引用它。因此,即使所有数据库在技术上都是全局可用的,任何给定的测试都只知道它自己的,并且只能引用它自己的。

(当然要注意性能。如果您发现自己创建了大型复杂的数据库,而对于小型的单独测试不应该这样做,那么同时创建许多这些数据库可能会减慢速度.)

关于c# - 一次运行所有测试会导致其中一些测试失败,但是当它们被单独触发时,它们就可以正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56648564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com