我正在使用EntityFrameworkCore 1.0,并试图设置一些简单的单元测试,但不断收到错误,大意是“添加了同一个键的项目。 。10.我不明白如何防止这种情况的发生我不明白的问题是什么,但不是为什么,以及如何解决EntityFramework核心测试内存数据库错误
首先我有一个测试,看起来像:
public void CanLoadAllAnnouncements()
{
var service = new AnnouncementControllerService(GenerateTestData.Generate());
var results = service.Get();
Assert.Equal(3, results.Count);
Assert.Equal("Test Announcement 1", results[0].Message);
Assert.Equal("Test Announcement 2", results[1].Message);
Assert.Equal("Test Announcement 3", results[2].Message);
}
你可以看到这是调用一个控制器服务类传递正在生成的内存数据库,这个类的代码看起来像这样。
public const string CurrentUserName = "testUserName";
public const string AlternateUserName = "anotherUserName";
public static DataContext Generate()
{
var context = new DataContext();
CreateRecentActivity(context);
CreateAnnouncement(context);
context.SaveChanges();
return context;
}
private static void CreateAnnouncement(DataContext context)
{
AddAnnouncement(context, -20, "Test Announcement 1", 1);
AddAnnouncement(context, -21, "Test Announcement 2", 2);
AddAnnouncement(context, -22, "Test Announcement 3", 3);
}
private static void CreateRecentActivity(DataContext context)
{
AddRecentActivity(context, -10, "Test Result 1", "#/TestResult1", CurrentUserName);
AddRecentActivity(context, -11, "Test Result 2", "#/TestResult2", CurrentUserName);
AddRecentActivity(context, -12, "Test Result 3", "#/TestResult3", CurrentUserName);
AddRecentActivity(context, -13, "Another Test Result 1", "#/AnotherTestResult1", AlternateUserName);
AddRecentActivity(context, -14, "Another Test Result 2", "#/AnotherTestResult2", AlternateUserName);
AddRecentActivity(context, -15, "Another Test Result 3", "#/AnotherTestResult3", AlternateUserName);
}
private static void AddAnnouncement(DataContext context, int id, string message, int ordering)
{
if (context.Announcements.All(ra => ra.Id != id))
{
context.Announcements.Add(new Announcement
{
Id = id,
Message = message,
Ordering = ordering
});
}
}
private static void AddRecentActivity(DataContext context, int id, string name, string url, string userName)
{
if (context.RecentActivities.All(ra => ra.Id != id))
{
context.RecentActivities.Add(new RecentActivity
{
Id = id,
Name = name,
Url = url,
UserName = userName
});
}
}
所以你可以看到它只是在检查到它还没有被添加之后,向每个DbSets添加一些项目。现在,如果我运行这个测试,它会整天工作,没有任何问题。
问题进场时,我添加了第二次测试,这样的事情
public void CanLoadAllRecentItemsForCurrentUser()
{
var service = new RecentActivityControllerService(GenerateTestData.Generate());
var results = service.Get(Testing.GenerateTestData.CurrentUserName);
Assert.Equal(3, results.Count);
Assert.Equal("Test Result 1", results[0].Name);
Assert.Equal("Test Result 2", results[1].Name);
Assert.Equal("Test Result 3", results[2].Name);
}
你可以看到,这个测试是非常相似的前一个。完成同样的事情,创建控制器服务,传入在generate方法中构建的db上下文的新实例。
这里是出现错误的地方。我假设问题是,上下文被生成为一个静态(即使我每次生成一个单独的实例)。并且由于测试正在并行运行,因此使用导致错误的相同密钥添加相同的项目。
我已经尝试删除GenerateTestData类(类,方法等)中静态的一切,并使用实例变量,但这没有什么区别。
我在这里错过了什么。我想为每个测试生成一个单独的内存数据库,以便它们之间不存在依赖关系。