title: Replace service with mocked using WebApplicationFactory
body: <p>I'm trying to replace an implementation of <code>IMessageFormatter</code> with a <code>MockMessageFormatter</code> for a test.</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class MyMockingWebApplicationFactory&lt;TStartUp&gt; : WebApplicationFactory&lt;Startup&gt;
  {
      protected override void ConfigureWebHost(IWebHostBuilder builder)
      {
          builder.ConfigureServices(services =&gt; { services.AddTransient&lt;IMessageFormatter, MockMessageFormatter&gt;(); });
      }
  }
  </code></pre>
  
  <p>The test looks like so:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class MockingTests : IClassFixture&lt;MyMockingWebApplicationFactory&lt;Startup&gt;&gt;
  {
      public MockingTests(MyMockingWebApplicationFactory&lt;Startup&gt; webApplicationFactory)
      {
          _webApplicationFactory = webApplicationFactory;
      }
  
      private readonly MyMockingWebApplicationFactory&lt;Startup&gt; _webApplicationFactory;
  
      [Fact]
      public async Task MockIt()
      {
          var client = _webApplicationFactory.WithWebHostBuilder(builder =&gt;
          {
              //builder.ConfigureServices(services =&gt;
              //{
              //    var foo = ServiceDescriptor.Transient&lt;IMessageFormatter, MessageFormatter&gt;();
              //    services.Remove(foo);
              //    services.AddTransient&lt;IMessageFormatter, MockMessageFormatter&gt;();
              //});
          }).CreateClient();
  
          var message = "Hello";
          var expectedReversedMessage = "foo";
          var result = await client.GetAsync($"/?message={message}");
          var content = await result.Content.ReadAsStreamAsync();
          var htmlParser = new HtmlParser();
          var htmlDocument = await htmlParser.ParseAsync(content);
          var messageElement = htmlDocument.GetElementById("original-message");
          var reversedMessageElement = htmlDocument.GetElementById("reversed-message");
          Assert.Equal(message, messageElement.InnerHtml);
          var reversedMessage = reversedMessageElement.InnerHtml;
          Assert.Equal(expectedReversedMessage, reversedMessage);
      }
  }
  </code></pre>
  
  <p>I've tried adding the call to <code>ConfigureServices</code> in the client and in the <code>MyMockingWebApplicationFactory</code> but the problem seems to be that the <em>real</em> <code>Startup</code> class is executed after the test's registration and so overwrites them.</p>
  
  <p>The <em>real</em> <code>StartUp</code> class is:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class Startup
  {
      public Startup(IConfiguration configuration)
      {
          Configuration = configuration;
      }
  
      public IConfiguration Configuration { get; }
  
      // This method gets called by the runtime. Use this method to add services to the container.
      public void ConfigureServices(IServiceCollection services)
      {
          services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); ;
          services.AddTransient&lt;IMessageFormatter, MessageFormatter&gt;();
      }
  
      // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
      public void Configure(IApplicationBuilder app, IHostingEnvironment env)
      {
          app.UseDeveloperExceptionPage();
          app.UseMvc();
      }
  }
  </code></pre>