Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一次运行所有测试会导致其中一些测试失败,但当它们';如果你一个人被解雇,那么他们工作得很好_C#_Visual Studio_.net Core_Xunit_Visual Studio 2019 - Fatal编程技术网

C# 一次运行所有测试会导致其中一些测试失败,但当它们';如果你一个人被解雇,那么他们工作得很好

C# 一次运行所有测试会导致其中一些测试失败,但当它们';如果你一个人被解雇,那么他们工作得很好,c#,visual-studio,.net-core,xunit,visual-studio-2019,C#,Visual Studio,.net Core,Xunit,Visual Studio 2019,我有一个奇怪的问题,每当我运行所有的测试时,我的一些测试都失败了,但是当我一个接一个地启动它们时,一切都正常 下面是在内存数据库中设置种子时失败的代码 它必须将一些权限s添加到权限表中,然后创建与权限有多对多关系的组s 基本上一个组可以有多个权限,一个权限可以在多个组中使用 但问题是 .Single抛出 序列包含多个元素 当所有测试同时运行时,但当它单独运行时,一切都正常 有什么想法吗 public class Tests : IDisposable { private readonly

我有一个奇怪的问题,每当我运行所有的测试时,我的一些测试都失败了,但是当我一个接一个地启动它们时,一切都正常

下面是在内存数据库中设置种子时失败的代码

它必须将一些
权限
s添加到
权限
表中,然后创建与权限有多对多关系的
s

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

但问题是

.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();
    }
}
公共类测试:IDisposable
{
私有只读上下文\u上下文;
公共空间处置()
{
_context.Database.EnsureDeleted();
}
公开考试()
{
var o=new DbContextOptionsBuilder();
o、 使用MemoryDatabase(“testDb”);
_上下文=新上下文(o.Options);
_context.Database.EnsureDeleted();
_context.Database.recreated();
}
[事实]
公共异步void myTest()
{
InitializePermissions(_context);
初始化器。初始化组(_上下文);
(...)
}
}
公共静态类初始值设定项
{
公共静态void InitializePermissions(上下文)
{
var permissionNames=新列表
{
“CanCreateNewProduct”,
“CanRemoveProduct”,
};
foreach(permissionNames中的var权限)
{
context.Permissions.Add(新权限(Permission));
}
SaveChanges();
}   
公共静态void初始化组(上下文)
{
var groups=newdictionary();
添加(“管理员”,新列表{“CanRemoveProduct”};
foreach(组中的var组)
{
foreach(group.Value中的var permissionName)
{
var permission=context.Permissions.Single(x=>x.Name==permissionName);
group.GroupPermissions.Add
(
新的许多
{
组=组,
GroupId=group.Id,
权限=权限,
PermissionId=permission.Id
}
);
}
context.Groups.Add(新组(Group.Key,权限);
}
SaveChanges();
}
}

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

(顺便说一句,如果你想知道为什么很多程序员会不遗余力地避免使用任何
static
,你会觉得他们的对象、依赖注入等过于复杂,而他们只能“使其成为静态”…这就是原因。)

您的
初始值设定项
可能会保持
静态
,只要它不在内部维护状态。由于您将数据库上下文的实例传递给它,因此它看起来至少不是一眼就能看到的。但是,当您继续在系统中工作时,必须保持此初始值设定项本身不维护任何状态ss测试

这就引出了内存中数据库本身:

o.UseInMemoryDatabase("testDb");
这些可在整个应用程序中全局访问。但您可以为它们指定唯一的名称。例如:

var dbName = Guid.NewGuid().ToString();
o.UseInMemoryDatabase(dbName);
这样,每个数据库上下文都应该有一个唯一的数据库,您可以在以后使用
dbName
在任何需要的地方引用该数据库。因此,即使所有数据库在技术上都是全局可用的,任何给定的测试都只知道自己的数据库,并且只能引用自己的数据库


(当然要注意性能。如果您发现自己正在创建大型复杂数据库,而这不应该用于小型的单个测试,那么一次创建许多数据库可能会降低速度。)

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

(顺便说一句,如果你想知道为什么很多程序员会不遗余力地避免使用任何
static
,你会觉得他们的对象、依赖注入等过于复杂,而他们只能“使其成为静态”…这就是原因。)

您的
初始值设定项
可能会保持
静态
,只要它不在内部维护状态。由于您将数据库上下文的实例传递给它,因此它看起来至少不是一眼就能看到的。但是,当您继续在系统中工作时,必须保持此初始值设定项本身不维护任何状态ss测试

这就引出了内存中数据库本身:

o.UseInMemoryDatabase("testDb");
这些可在整个应用程序中全局访问。但您可以为它们指定唯一的名称。例如:

var dbName = Guid.NewGuid().ToString();
o.UseInMemoryDatabase(dbName);
这样,每个数据库上下文都应该有一个唯一的数据库,您可以在以后使用
dbName
在任何需要的地方引用该数据库。因此,即使所有数据库在技术上都是全局可用的,任何给定的测试都只知道自己的数据库,并且只能引用自己的数据库


(当然要注意性能。如果您发现自己正在创建大型复杂数据库,而这不应该用于小型的单独测试,那么一次创建许多这样的数据库可能会降低速度。)

听起来您的测试是共享状态。每个测试都应该完全隔离,不依赖于外部或共享状态。可能不使用单一的
静态
内存结构,而是使用相同的结构,但基于实例,每个测试创建/使用/处置自己的实例?每个数据库也需要隔离,因此
 UseInMemoryDatabase(“testDb”)
需要为每个测试提供单独的数据库名称。将
UseInMemoryDatabase(“testDb”)
更改为
UseInMemoryDatabase(Guid.NewGuid().ToString());
已完成