thể trùng lặp:
Using IoC for Unit TestingKết hợp Unit Tests (chế giễu) và một khung tiêm dependecy
Tôi nghĩ rằng tôi có một vấn đề hiểu biết về thử nghiệm cách Unit và/hoặc Dependency Injection là đang làm việc. Tôi đang sử dụng NUnit và Rhino Mocks để kiểm tra Đơn vị và Ninject như một Khuôn khổ Khuôn khổ phụ thuộc. Nói chung, tôi mặc dù cả hai sẽ phù hợp với perfeclty - nhưng bằng cách nào đó, nó có vẻ như nó được chỉ phức tạp hơn và khó hiểu hơn.
(Tôi sẽ cố gắng tạo nên một ví dụ tốt, để giữ cho nó sạch sẽ và dễ dàng. Đó là về tôi, đi xe đạp).
1.) Nếu không có DI/Unit Tests:
Mà không biết của DI và đơn vị xét nghiệm, mã của tôi đã có thể nhìn như thế - và tôi muốn được hạnh phúc:
public class Person
{
public void Travel()
{
Bike bike = new Bike();
bike.Ride();
}
}
public class Bike
{
public void Ride()
{
Console.WriteLine("Riding a Bike");
}
}
Để đi xe của tôi xe đạp i sẽ chỉ cần: new Person().Travel();
2.) Với DI:
tôi không muốn điều đó khớp nối chặt chẽ, vì vậy tôi cần một giao diện và một NinjectModule! Tôi có một số Overhead, nhưng điều đó sẽ ổn, miễn là mã dễ đọc và dễ hiểu. Tôi sẽ chỉ vượt qua mã cho lớp người biến đổi, lớp Bike là không thay đổi:
public class Person
{
IKernel kernel = new StandardKernel(new TransportationModule());
public void Travel()
{
ITransportation transportation = kernel.Get<ITransportation>();
transportation.Ride();
}
}
tôi vẫn có thể đi xe đạp của tôi với chỉ: new Person().Travel();
3.) Xét Unit-Testing (không có DI):
Để có thể kiểm tra xem Phương pháp đi xe có được gọi đúng cách hay không, tôi sẽ cần một Mô hình. Theo tôi biết, có hai cách để tiêm một giao diện: Tiêm xây dựng và Setter Injection. Tôi chọn Constructor tiêm ví dụ của tôi:
public class Person
{
ITransportation transportation;
public person(ITransportation transportation)
{
this.transportation = transportation;
}
public void Travel()
{
transportation.Ride();
}
}
Lần này, tôi sẽ neet để vượt qua xe đạp: new Person(new Bike()).Travel();
4.) Với DI và chuẩn bị cho đơn vị xét nghiệm
Lớp trong 3. Xét đơn vị kiểm tra (không có DI) sẽ thực hiện công việc mà không sửa đổi, nhưng tôi cần phải gọi new Person(kernel.Get<ITransportation>());
. Thông qua đó, nó cảm thấy như tôi đang mất lợi ích từ DI - lớp người có thể gọi du lịch mà không cần bất kỳ khớp nối và bất kỳ cần phải biết loại lớp giao thông vận tải là. Ngoài ra, tôi nghĩ rằng biểu mẫu này thiếu nhiều khả năng đọc của ví dụ 2.
Đây có phải là cách thực hiện không? Hoặc là có cách nào khác - thanh lịch hơn để đạt được Dependency Injection và khả năng kiểm tra đơn vị (và giả lập)?
(Nhìn lại, có vẻ như ví dụ này thực sự tồi tệ - mọi người nên biết loại thiết bị giao thông nào anh ta đang cưỡi tại thời điểm này ...)
Tôi nghĩ bạn có thể bị nhầm lẫn về các định nghĩa về Dependency Injection (DI) và Inversion of Control (IoC). Bạn là con số thứ ba * thực hiện * thực hiện DI (bạn đã di chuyển phụ thuộc vào hàm tạo), con số thứ hai của bạn đang sử dụng thùng chứa IoC (Ninject) để giải quyết các phụ thuộc. –
zapthedingbat là đúng. Bạn đang thực hiện DI trong ví dụ thứ ba, nhưng không sử dụng vùng chứa DI, điều này là tốt. DI container là tùy chọn khi thực hiện DI. – Steven
Ví dụ "2." không sử dụng DI, nhưng là "Dịch vụ định vị" ... –