Like Unit Test Startup.cs in .NET Core

How do people go to unit test their Startup.cs classes in .NET Core 2? Do all functions appear to be provided by static extension methods that are not simulated?

If you take this method ConfigureServices, for example:

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

    services.AddMvc();
}

How can I write tests to ensure that AddDbContext (...) and AddMvc () are called, the choice of implementing this whole function with extension methods seems to have made it unselected?

+21
source share
3 answers

, , AddDbContext services, . , .

Startup class - . , , ( ASP.NET Core).

, :

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

, Startup ISomeDependency. ISomeDependency , . , , , . .

, , . , .

Unit Test, - . , , . , . , , .

:

[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);
}
+23

MVC, , , .

public void AddTransactionLoggingCreatesConnection()
{
     var servCollection = new ServiceCollection();

    //Add any injection stuff you need here
    //servCollection.AddSingleton(logger.Object);

    //Setup the MVC builder thats needed
    IMvcBuilder mvcBuilder = new MvcBuilder(servCollection, new Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager());

    IEnumerable<KeyValuePair<string, string>> confValues = new List<KeyValuePair<string, string>>()
    {
        new KeyValuePair<string, string>("TransactionLogging:Enabled", "True"),
        new KeyValuePair<string, string>("TransactionLogging:Uri", "https://api.something.com/"),
        new KeyValuePair<string, string>("TransactionLogging:Version", "1"),
        new KeyValuePair<string, string>("TransactionLogging:Queue:Enabled", "True")
    };

    ConfigurationBuilder builder = new ConfigurationBuilder();
    builder.AddInMemoryCollection(confValues);

    var confRoot = builder.Build();
    StartupExtensions.YourExtensionMethod(mvcBuilder); // Any other params
}
0

, , WebHost AspNetCore , program.cs, , . IServices .ConfigureServices , , , .

, , , , . , .

[TestClass]
public class StartupTests
{
    [TestMethod]
    public void StartupTest()
    {
        var webHost = Microsoft.AspNetCore.WebHost.CreateDefaultBuilder().UseStartup<Startup>().Build();
        Assert.IsNotNull(webHost);
        Assert.IsNotNull(webHost.Services.GetRequiredService<IService1>());
        Assert.IsNotNull(webHost.Services.GetRequiredService<IService2>());
    }
}

public class Startup : MyStartup
{
    public Startup(IConfiguration config) : base(config) { }
}
0

All Articles