2012-03-28 21 views
5

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.

+0

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

+0

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. –

+0

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ố. –

Trả lời

3

Tôi gặp sự cố tương tự sáng nay. Vấn đề là do mệnh đề where trong phương thức seed. Có thể chỉnh lại này (bây giờ) được viết lại này:

var dinner = context.Dinners.ToList().Where(d => d.Country == "England").Single(); 

Mặc dù không hiệu quả (tất cả các đối tượng được lấy từ cơ sở dữ liệu và lọc sẽ được thực hiện trong bộ nhớ), nó đã giải quyết ObjectDisposedException trong các thử nghiệm đơn vị của tôi. Trong trường hợp của tôi, tôi chỉ có một vài đồ vật, vì vậy tôi có thể sống với nó ngay bây giờ.

+0

Cảm ơn câu trả lời của bạn Jos. Bạn đã cách ly vấn đề này như thế nào? –

+1

Tôi mất khá nhiều thời gian để tìm hiểu vì tôi đã nghĩ rằng vấn đề là do cấu hình IoC gây ra, vì DisposedException. Tôi nên biết rõ hơn, tôi không thay đổi bất cứ thứ gì ở đó và nó đã hoạt động trước đó. Tôi đã có một kịch bản làm việc, sửa đổi mã hạt giống với các mô hình bổ sung (với mệnh đề where được giới thiệu), tiếp tục bình luận mã mới được giới thiệu cho đến khi vấn đề không xảy ra. Bỏ ghi chú mã mệnh đề where và Exception đã trở lại. Truy tìm lỗi đơn giản nhưng hiệu quả trong trường hợp khung nguồn đóng cho phép bạn xuống. –