c# - 一次运行所有测试会导致其中一些测试失败,但是当它们被单独解雇时,它们可以正常工作
问题描述
我有一些奇怪的问题,我的一些测试在我Run all
测试时都会失败,但是当我一个接一个地启动它们时,一切正常
这是播种失败的代码InMemoryDatabase
它必须向表中添加一些Permission
s Permissions
,然后创建Group
与权限具有多对多关系的 s
基本上一个Group可以有很多权限,一个权限可以在很多组中使用
但问题是
.Single
投掷
序列包含多个元素
当所有测试同时运行,但单独运行时一切正常
任何想法?
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
,并且您觉得他们的对象、依赖注入等过于复杂,而他们可以“使其成为静态”......这个也就是为什么。)
只要它不内部保持状态,您Initializer
就可以保留。static
至少一目了然,因为您将数据库上下文的实例传递给它。但是当你继续在你的系统中工作时,重要的是要保持这个初始化程序在测试中不保持任何状态。
然后将我们带到内存数据库本身:
o.UseInMemoryDatabase("testDb");
这些可以在整个应用程序中全局访问。 但是你可以给他们唯一的名字。例如:
var dbName = Guid.NewGuid().ToString();
o.UseInMemoryDatabase(dbName);
有了这个,每个数据库上下文都应该有一个唯一的数据库,您可以稍后dbName
在您可能需要的任何地方引用它。因此,即使所有数据库在技术上都是全球可用的,任何给定的测试都只知道它自己的,并且只能引用它自己的。
(当然要注意性能。如果您发现自己创建了大型复杂数据库,而您不应该将其用于小型个人测试,那么一次创建许多这样的数据库可能会减慢速度。)
推荐阅读
- java - 爪哇。百里香叶。CRUD 操作后页面上的所有 .CSS 样式消失
- delphi - 从 VirtualTreeView 拖放到 shell(Ole 拖放)
- shell - 在 Linux / OSX 中将文件上移一个目录
- java - 如何让 Jersey 应用程序打印 Tomcat 服务器中的错误日志
- node.js - 无法在 fabric-contract-api 中使用接口
- batch-file - 比较两个文件并使用 LIKE 值输出
- python - 拆分连接成一个字符串的单独项目集,分隔符为 ','
- apache-poi - 易受攻击的 ooxml-schemas-1.4.jar
- c# - 如何安装 netstandard.dll v4.0.2.0.0.0
- cmake - CMake:将自定义命令添加到 ExternalProject_Add()