2017-11-25 43 views
6

Làm thế nào để mọi người đi về Unit Testing các lớp Startup.cs của họ trong một ứng dụng .NET Core 2? Tất cả các chức năng dường như được cung cấp bởi các phương pháp mở rộng tĩnh mà không phải là mockable?Làm thế nào để Unit Test Startup.cs trong .NET Core

Nếu bạn mất phương pháp ConfigureServices này ví dụ:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDbContext<BlogContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

    services.AddMvc(); 
} 

Làm thế nào tôi có thể viết các bài kiểm tra để đảm bảo rằng AddDbContext (...) & AddMvc() được gọi, Sự lựa chọn thực hiện tất cả các chức năng này thông qua Phương pháp mở rộng dường như đã làm cho nó không thể chữa được?

+0

Đối với trường hợp này, tôi viết bài kiểm tra tích hợp để có được những đường ống hoàn chỉnh được kiểm tra. Bạn có thể sử dụng some.g. IoC để tiêm một số chức năng mà bạn có thể thử. – DotNetDev

Trả lời

6

Vâng vâng, nếu bạn muốn kiểm tra thực tế là phương pháp tiện ích mở rộng AddDbContext đã được gọi trên services bạn gặp sự cố. Điều tốt là bạn không nên kiểm tra chính xác thực tế này.

Startup lớp học là một ứng dụng composition root. Và khi thử nghiệm một thành phần gốc bạn muốn kiểm tra xem nó có thực sự đăng ký tất cả các phụ thuộc cần thiết cho việc khởi tạo các đối tượng gốc (các bộ điều khiển trong trường hợp ứng dụng ASP.NET Core) hay không.

Giả sử bạn có điều khiển sau đây:

public class TestController : Controller 
{ 
    public TestController(ISomeDependency dependency) 
    { 
    } 
} 

Bạn có thể thử kiểm tra xem Startup đã đăng ký kiểu cho ISomeDependency. Nhưng việc thực hiện ISomeDependency cũng có thể yêu cầu một số phụ thuộc khác mà bạn nên kiểm tra. Cuối cùng bạn kết thúc với một thử nghiệm có nhiều kiểm tra cho các phụ thuộc khác nhau nhưng nó không thực sự đảm bảo rằng độ phân giải đối tượng sẽ không ném ngoại lệ phụ thuộc bị thiếu. Không có quá nhiều giá trị trong một thử nghiệm như vậy.

Cách tiếp cận hoạt động tốt đối với tôi khi kiểm tra gốc thành phần là sử dụng vùng chứa tiêm phụ thuộc thực. Sau đó, tôi gọi một thành phần gốc trên nó và khẳng định rằng độ phân giải của đối tượng gốc không ném.

Nó không thể được coi là thử nghiệm đơn vị thuần túy bởi vì chúng tôi sử dụng lớp không được xếp lớp khác. Nhưng các thử nghiệm như vậy, không giống như các bài kiểm tra tích hợp khác, nhanh và ổn định. Và điều quan trọng nhất là họ mang giá trị của kiểm tra hợp lệ cho đăng ký phụ thuộc chính xác. Nếu kiểm tra như vậy vượt qua bạn có thể chắc chắn rằng đối tượng cũng sẽ được tạo ra một cách chính xác trong sản phẩm.

Đây là một mẫu thử nghiệm như:

[TestMethod] 
public void ConfigureServices_RegistersDependenciesCorrectly() 
{ 
    // Arrange 

    // Setting up the stuff required for Configuration.GetConnectionString("DefaultConnection") 
    Mock<IConfigurationSection> configurationSectionStub = new Mock<IConfigurationSection>(); 
    configurationSectionStub.Setup(x => x["DefaultConnection"]).Returns("TestConnectionString"); 
    Mock<Microsoft.Extensions.Configuration.IConfiguration> configurationStub = new Mock<Microsoft.Extensions.Configuration.IConfiguration>(); 
    configurationStub.Setup(x => x.GetSection("ConnectionStrings")).Returns(configurationSectionStub.Object); 

    IServiceCollection services = new ServiceCollection(); 
    var target = new Startup(configurationStub.Object); 

    // Act 

    target.ConfigureServices(services); 
    // Mimic internal asp.net core logic. 
    services.AddTransient<TestController>(); 

    // Assert 

    var serviceProvider = services.BuildServiceProvider(); 

    var controller = serviceProvider.GetService<TestController>(); 
    Assert.IsNotNull(controller); 
} 
+1

Cảm ơn CodeFuller, đó là phiên bản cụ thể của ServiceCollection mà tôi đã bỏ lỡ, tôi chỉ có thể cho phép bộ sưu tập được xây dựng sau đó xác thực đầu ra để xác nhận rằng các cuộc gọi chính xác đã được thực hiện. Đẹp nhất! –

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