Câu hỏi và mã của tôi dựa trên bài đăng trên blog Code First Entity Framework Unit Test Examples. Tôi đang sử dụng SQL Compact 4.0 và như vậy các bài kiểm tra đơn vị của tôi đang chạy với cơ sở dữ liệu thực tế bằng cách sử dụng dữ liệu thực tương tự như những gì đang được mô tả trong bài đăng trên blog.Mã khuôn khổ thực thể Trước tiên: Cách tạo một cơ sở dữ liệu để thử nghiệm đơn vị
Tôi muốn tạo cơ sở dữ liệu sản xuất với giá trị mặc định trong một số bảng nhưng khi chạy thử nghiệm đơn vị của tôi, tôi muốn thêm dữ liệu bổ sung và cập nhật một số giá trị mặc định.
Tôi đã tạo một lớp Trình khởi tạo tùy chỉnh giống như cơ sở dữ liệu với các giá trị mặc định. Đối với đơn vị xét nghiệm của tôi, tôi đã tạo ra một Initializer tùy chỉnh mà được thừa hưởng từ người đầu tiên mà không giống các thử nghiệm cụ thể và/hoặc sửa đổi:
public class NerdDinnersInitializer : DropCreateDatabaseIfModelChanges<NerdDinners>
{
protected override void Seed(NerdDinners context)
{
var dinners = new List<Dinner>
{
new Dinner()
{
Title = "Dinner with the Queen",
Address = "Buckingham Palace",
EventDate = DateTime.Now,
HostedBy = "Liz and Phil",
Country = "England"
}
};
dinners.ForEach(d => context.Dinners.Add(d));
context.SaveChanges();
}
}
public class NerdDinnersInitializerForTesting : NerdDinnersInitializer
{
protected override void Seed(NerdDinners context)
{
base.Seed(context);
var dinner = context.Dinners.Where(d => d.Country == "England").Single();
dinner.Country = "Ireland";
context.SaveChanges();
}
}
tôi cũng sử dụng một lớp cơ sở cho các bài kiểm tra đơn vị của tôi mà khởi tạo cơ sở dữ liệu thử nghiệm như vậy:
[TestClass]
public abstract class TestBase
{
protected const string DbFile = "test.sdf";
protected const string Password = "1234567890";
protected NerdDinners DataContext;
[TestInitialize]
public void InitTest()
{
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", "",
string.Format("Data Source=\"{0}\";Password={1}", DbFile, Password));
Database.SetInitializer(new NerdDinnersInitializerForTesting());
DataContext = new NerdDinners();
DataContext.Database.Initialize(true);
}
[TestCleanup]
public void CleanupTest()
{
DataContext.Dispose();
if (File.Exists(DbFile))
{
File.Delete(DbFile);
}
}
}
các đơn vị kiểm tra thực tế trông như thế này:
[TestClass]
public class UnitTest1 : TestBase
{
[TestMethod]
public void TestMethod1()
{
var dinner = new Dinner()
{
Title = "Dinner with Sam",
Address = "Home",
EventDate = DateTime.Now,
HostedBy = "The wife",
Country = "Italy"
};
DataContext.Dinners.Add(dinner);
DataContext.SaveChanges();
var savedDinner = (from d in DataContext.Dinners
where d.DinnerId == dinner.DinnerId
select d).Single();
Assert.AreEqual(dinner.Address, savedDinner.Address);
}
}
Khi tôi chạy thử nghiệm truy vấn LINQ rằng fetches savedDinner không thành công với các "Trường hợp ObjectContext đã được xử lý và không còn có thể được sử dụng cho các hoạt động yêu cầu kết nối nữa." ngoại lệ. Tôi không thể giải thích tại sao.
Là những gì tôi đang làm ở đây một mô hình chấp nhận được và bất cứ ai có thể làm sáng tỏ một số lý do tại sao điều này không hoạt động?
Cảm ơn.
Tôi không thể thấy lý do nào khiến bối cảnh đối tượng bị xử lý. Bạn có thể gỡ lỗi thử nghiệm đơn vị của bạn và đặt một điểm break để phương pháp savechanges và kiểm tra xem datacontext là không null? sau đó xin vui lòng setp vào dòng tiếp theo và kiểm tra xem datacontext là null. – daryal
Hi Daryal, datacontext không phải là null trong cả hai trường hợp. DataContext.SaveChanges(); hoạt động tốt, nó là truy vấn LINQ sau khi nó thất bại mặc dù datacontext không phải là null. –
Tôi có thể nghiên cứu về DataContext.Dinners mà không gặp vấn đề gì. Lưu ý, lỗi tôi đã nói rằng ObjectContext đã được xử lý, không phải là DataContext. Tôi không biết nếu ObjectContext là giống như DataContext trong truy vấn LINQ. Dù sao, làm như sau: var initDb = new SvDataContext(); initDb.Database.Initialize (true); DataContext = new SvDataContext(); trong phương pháp InitTest của tôi khắc phục sự cố. –