Search code examples
c#unit-testing.net-corexunit.netkestrel-http-server

Kestrel not listening in xUnit test


I'm using this custom server for unit-testing where I initialize it with MyStarup that loads a single middleware that I need for testing.

This has worked before with net47 and it stopped after I switched the project to .net-core. It now gives me this very helpful exception:

System.Net.Sockets.SocketException No connection could be made because the target machine actively refused it 127.0.0.1:30001

I create it from a IClassFixture with a factory method and call it with a HttpClient that I also create with a factory method and get it from the same fixture.

public class MyServer : IDisposable
{
    private readonly IWebHost _host;        

    public MyServer(string url) // <-- http://localhost:30001
    {
        _host =
            new WebHostBuilder()
                .UseKestrel()
                .UseUrls(url)                    
                .UseStartup<MyStartup>()
                .Build();

        Task = _host.StartAsync(); // <-- tried RunAsync too, no difference
    }

    public Task Task { get; set; }

    public void Dispose()
    {
        _host.Dispose();
    }
}

So my question is, how can I make it work again?

I read this Why Kestrel doesn't listen at specified port? but it doesn't help solve it. I cannot run it as a console and it was working before. Why has it stopped after switching to .net-core?


Solution

  • I figured it out. You need to use a custom configuration to specify the urls value for Kestrel, otherwise it's using some random (?) or default port 5001. I didn't want to use hosting.json so I used the InMemoryCollection

        public MyServer(string url)
        {
            var configuration =
                new ConfigurationBuilder()
                    .AddInMemoryCollection(new Dictionary<string, string>
                    {
                        ["urls"] = url
                    })
                    .Build();
    
            _host =
                new WebHostBuilder()
                    .UseKestrel()
                    //.UseUrls(url) // <-- cannot use this, seems to be deprecated
                    //.Configure(app => { app.UsePathBase(url); }) // <-- does not work
                    .UseConfiguration(configuration)
                    .UseStartup<MyStartup>()
                    .Build();
    
            Task = _host.StartAsync();
        }