2017-11-25 1 views
6

사람들이 .NET Core 2 응용 프로그램에서 Startup.cs 클래스를 테스트하는 방법은 무엇입니까? 모든 기능은 mockable이 아닌 Static 확장 메소드에 의해 제공되는 것 같습니다..NET Core의 Startup.cs 테스트 단위 방법

당신은 예를 들어이 ConfigureServices 방법을 취할 경우

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

    services.AddMvc(); 
} 

을 내가 AddDbContext (...) & AddMvc()가 호출되는 것을 보장하기 위해 테스트를 쓸 수있는 방법을 통해이 모든 기능을 구현의 선택 확장 메서드를 사용하여 테스트 할 수없는 것으로 보입니다.

+0

: 여기

는 테스트 샘플입니다. some.g 사용할 수 있습니다. IoC에서 모의 ​​할 수있는 기능을 주입합니다. – DotNetDev

답변

6

그래, 확장 방법 AddDbContext이 (가) services에 전화되었다는 사실을 확인하려면 문제가있는 것입니다. 좋은 점은 실제로이 사실을 정확하게 확인하면 안된다는 것입니다.

Startup 클래스는 응용 프로그램 composition root입니다. 컴포지션 루트를 테스트 할 때 루트 객체 (ASP.NET 코어 응용 프로그램의 경우 컨트롤러)의 인스턴스화에 필요한 모든 종속성을 실제로 등록했는지 확인하려고합니다. 당신은 StartupISomeDependency의 유형을 등록 여부 확인을 시도 할 수

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

:

는 다음 컨트롤러가 말한다. 그러나 ISomeDependency을 구현하려면 검사해야하는 다른 종속성이 필요할 수도 있습니다. 결과적으로 서로 다른 종속성에 대한 검사가 수 많은 검사로 끝나지 만 실제로 개체 확인으로 인해 누락 된 종속성 예외가 발생하지는 않습니다. 그러한 테스트에는 너무 많은 가치가 없습니다.

구성 루트를 테스트 할 때 나에게 잘 맞는 방법은 실제 의존성 주입 컨테이너를 사용하는 것입니다. 그런 다음 컴포지션 루트를 호출하고 루트 객체의 해상도가 떨어지지 않는다고 주장합니다.

다른 스텁되지 않은 클래스를 사용하기 때문에 순수한 단위 테스트로 간주 될 수 없습니다. 그러나 이러한 테스트는 다른 통합 테스트와 달리 빠르고 안정적입니다. 그리고 가장 중요한 것은 올바른 종속성 등록을위한 유효한 검사 값을 가져 오는 것입니다. 그러한 테스트가 통과되면 객체가 제품에서 올바르게 인스턴스화되는지도 확인할 수 있습니다. 내가 통합 테스트 테스트 전체 파이프 라인을 얻을 쓰기이 경우에

[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

감사합니다. CodeFuller, 제가 누락 된 ServiceCollection의 구체적인 버전이었습니다. 콜렉션을 빌드 한 다음 정확한 호출이 수행되었는지 확인하기 위해 출력의 유효성을 검사하도록 할 수 있습니다. 좋은 분! –