Set the IHostingEnvironment in unit test

33.3k views Asked by At

I am currently upgrading a project from .NET Core RC1 to the new RTM 1.0 version. In RC1, there was a IApplicationEnvironment which was replaced with IHostingEnvironment in version 1.0

In RC1 I could do this

public class MyClass
{
    protected static IApplicationEnvironment ApplicationEnvironment { get;private set; }

    public MyClass()
    {
        ApplicationEnvironment = PlatformServices.Default.Application;
    }
}

Does anyone know how to achieve this in v1.0?

public class MyClass
{
    protected static IHostingEnvironment HostingEnvironment { get;private set; }

    public MyClass()
    {
        HostingEnvironment = ???????????;
    }
}
4

There are 4 answers

4
Shimmy Weitzhandler On

Using Microsoft.Extensions.Hosting (which is one of the included packages in ASP.NET Core), you can use:

IHostEnvironment env = 
    new HostingEnvironment { EnvironmentName = Environments.Development };
2
Set On

In general, as IHostingEnvironment is just an interface, you can simply mock it to return whatever you want.

If you are using TestServer in your tests, the best way to mock is to use WebHostBuilder.Configure method. Something like this:

var testHostingEnvironment = new MockHostingEnvironment(); 
var builder = new WebHostBuilder()
            .Configure(app => { })
            .ConfigureServices(services =>
            {
                services.TryAddSingleton<IHostingEnvironment>(testHostingEnvironment);
            });
var server = new TestServer(builder);
3
Nkosi On

You can mock the IHostEnvironment using a mocking framework if needed or create a fake version by implementing the interface.

Give a class like this...

public class MyClass {
    protected IHostingEnvironment HostingEnvironment { get;private set; }

    public MyClass(IHostingEnvironment host) {
        HostingEnvironment = host;
    }
}

You can setup a unit test example using Moq...

public void TestMyClass() {
    //Arrange
    var mockEnvironment = new Mock<IHostingEnvironment>();
    //...Setup the mock as needed
    mockEnvironment
        .Setup(m => m.EnvironmentName)
        .Returns("Hosting:UnitTestEnvironment");
    //...other setup for mocked IHostingEnvironment...

    //create your SUT and pass dependencies
    var sut = new MyClass(mockEnvironment.Object);

    //Act
    //...call you SUT

    //Assert
    //...assert expectations
}
0
Gabrielkdc On

This is how we do it in our tests:

     var serviceProvider =  new ServiceCollection()
        .AddScoped<IHostingEnvironment, MockHostingEnvironment>()
        .AddScoped<IAccessPointService, AccessPointService>()
          .BuildServiceProvider();

The definition of MockHosting, you can change the implementation for something to fit your needs:

 public class MockHostingEnvironment : IHostingEnvironment
{
    public string EnvironmentName { get => return "Testing"; set => throw new NotImplementedException(); }
    public string ApplicationName { get => "My App"; set => throw new NotImplementedException(); }
    public string ContentRootPath { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
    public IFileProvider ContentRootFileProvider { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}

Finally, we just ask the service provider an instance of the Class needing the DI:

    var accessPointService = serviceProvider.GetService<IAccessPointService>();