2015-10-15 12 views
6

Tôi có một công việc mà tôi có một DbContext IDisposable. Tôi muốn đơn vị kiểm tra công việc này mà không cần nhấn vào cơ sở dữ liệu. Tôi phải làm gì để làm điều này?Làm thế nào để đối phó với một kho lưu trữ IDisposable với Unity?

Im sử dụng lắp ráp Fakes mặc định 'của microsoft.

Công việc của tôi:

public void Work() 
{ 
    do 
    { 
     //code here     
     using (var repository = new Repository<User>()) 
     { 
      repository.Save(user); 
     } 

    } while (true); 
} 

Tôi đang cố gắng để kiểm tra và trong phần này của bài kiểm tra nó không thành công bởi vì nó thực sự tạo ra một thể hiện mới của lớp Repository.

Phương pháp thử nghiệm của tôi:

using (ShimsContext.Create()) 
{ 
    Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.Constructor = (a) => { }; 

    Data.Repository.Fakes.ShimRepository<Domain.Fakes.ShimUser>.AllInstances.SaveT0 = (a, b) => 
    { 
    }; 

    var service = GetService(); 
    service.Work(); //Throws exception 
} 

Làm thế nào tôi có thể giả phương pháp Save này?

+1

xem Dependency Injection - bạn cần cho phép tham số được truyền vào Work() Hoặc ít nhất là vào dịch vụ nếu không nó luôn tạo ra một thực tế. –

+0

Tôi không quen với Hàng giả, nhưng có lẽ nó không đủ đầy đủ tính năng cho nhu cầu của bạn. Tôi biết điều này là tầm thường với một thư viện như Moq (https://github.com/Moq/moq4). –

+0

Nó sẽ không tầm thường với Moq, kể từ khi ông là instantiating một ví dụ cụ thể thực tế của kho lưu trữ trong công việc. –

Trả lời

7

Bạn đã vi phạm DIP tại đây, khiến đơn vị kiểm tra dịch vụ của bạn khó khăn hơn rất nhiều so với mức cần thiết. Bạn cũng nên tránh các kho lưu trữ chung và ủng hộ role interfaces.

Thay vào đó, hãy đưa dịch vụ trừu tượng vào kho lưu trữ của bạn, ví dụ: IUsersRepository xác định phương thức Save của bạn. Sau đó, trong thử nghiệm đơn vị dịch vụ của bạn, bạn có thể chỉ cần sử dụng triển khai sơ khai là IUsersRepository.

+0

Có, nhưng làm thế nào về việc vứt bỏ vật thể? Nếu tôi tiêm nó một lần, công việc sẽ chạy mãi mãi với trường hợp đầu tiên của bối cảnh. – gog

+0

Gỡ bỏ là một chi tiết triển khai thực hiện khung thực thể của trừu tượng. Do đó việc xử lý được thực hiện trong ví dụ: EntityFrameworkUsersRepository. – devdigital

2

Fakes có xu hướng tiết lộ rằng mã của bạn không đúng cách sau khi D trong RẮN kể từ khi bạn đang tạo ra phụ thuộc bên trong lớp học của bạn thay vì đi qua chúng trong.

một mô hình tốt hơn nhiều sẽ tạo ra một giao diện ISaveRepository mà lần lượt triển khai IDisposable với phương thức Save() được hiển thị. Sau đó bạn nên tiêm một thể hiện của kho lưu trữ của bạn vào lớp của bạn. Điều này sẽ cho phép bạn thỏa mãn việc sử dụng câu lệnh kiểm tra, cũng như thực hiện một mô hình xác định phương thức .Save() không nhấn vào cơ sở dữ liệu.

public class Test 
{ 
    private readonly ISaveRepository _userRepository; 

    public Test(ISaveRepository userRepository) 
    { 
     _userRepository = userRepository; 
    } 

    public void Work() 
    { 
     using (_userRepository) 
     { 
      var cont = true; 
      do 
      {    
       _userRepository.Save(new User()); 
       cont = false; 
      } while (cont); 
     } 
    } 
} 

public interface ISaveRepository : IDisposable 
{ 
    void Save<T>(T model); 
} 

public class Repository<T> : ISaveRepository 
{ 
    public void Dispose() { } 
    public void Save<TT>(TT model) {} 
} 

public class User {} 
+0

Làm thế nào Dispose sẽ không được yêu cầu cho nhiều triển khai? – gog

+0

Việc triển khai sơ khai của bạn có cần phải vứt bỏ không? Một kho lưu trữ XML có cần xử lý không? Một kho lưu trữ cuộc gọi dịch vụ web có cần vứt bỏ không? v.v. – devdigital

+0

@ggui Tôi giả sử sau đó bạn đã tạo lại kết nối ban đầu để tránh giữ kết nối trong một khoảng thời gian dài? –

Các vấn đề liên quan