Search code examples
c#asp.net-core.net-coreintegration-testing

Why is the ConfigureWebHost(IWebHostBuilder builder) of the WebApplicationFactory class not being called?


I am writing an integration test, following its MSdoc.

I am using a Custom WebApplicationFactory<Program>, where I need to override the ConfigureWebHost(IWebHostBuilder builder) method to register some services and use a database of my choice, different from the one in prod.

The problem is this method is not being called. I'm doing exactly what that doc did, only that I'm not using XUnit. I use MSTest, which does not have the magical IClassFixture type.

I have tried the ConfigureTestServices and ConfigureServices


protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            base.ConfigureWebHost(builder);
            builder.UseEnvironment(Environments.Development)
                .ConfigureTestServices(services =>
            {
                var dbContextDescriptor = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(DbContextOptions<MyDbContext>));

Why is the method not being called and how do I get it called?

Edit Adding my setup

The test itself, inheriting the CustomWebApplicationFactory class

 [TestClass]
 public class TransactionTest : CustomWebApplicationFactory<Program>
 {
    private readonly CustomWebApplicationFactory<Program> _factory;

    public TransactionTest(
            CustomWebApplicationFactory<Program> factory)
    {
       this._factory = factory;
    }
    [TestMethod]
    public async Task Only_existing_users_can_transact()
    {

       var requestParam = new MyRequest
       {
         phone = "12345678",
       };
       ... some more code for acting and assertion
    }
}

The setup

public class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram> where TProgram : class
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            base.ConfigureWebHost(builder);
            builder.ConfigureServices(services =>
            { 
//Adding a breakpoint here does nothing. The breakpoint is never hit
                var dbContextDescriptor = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(DbContextOptions<AppDbContext>));

                services.Remove(dbContextDescriptor);

                var dbConnectionDescriptor = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(DbConnection));

                services.Remove(dbConnectionDescriptor);

                
            });

            builder.UseEnvironment("Development");
        }
    }


Solution

  • When you use MSTest or NUnit you have to initialize WebApplicationFactory.

    [TestClass]
    public sealed class ExampleTests : IDisposable
    {
        private CustomWebApplicationFactory<Program> webApplicationFactory;
    
        public void Dispose()
        {
            this.webApplicationFactory.Dispose();
        }
    
        [TestCleanup]
        public void TestCleanup()
        {
            this.webApplicationFactory.Dispose();
        }
        
        [TestMethod]
        public async Task TestMethodToTestSomething()
        {
            // Arrange
            this.webApplicationFactory = new CustomWebApplicationFactory<Program>();
    
            var httpClient = this.webApplicationFactory.CreateClient();
    
            // Act
            // ...
    
            // Assert
            // ...
        }
    }
    

    Side note:
    Usually, when I need to change registered services, I don't customize WebApplicationFactory (as you) but customize the client with WithWebHostBuilder().