我正在使用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類(類,方法等)中靜態的一切,並使用實例變量,但這沒有什麼區別。
我在這裏錯過了什麼。我想爲每個測試生成一個單獨的內存數據庫,以便它們之間不存在依賴關係。