Setting folder for ASP.NET Core integration tests

861 views Asked by At

I have two projects. One is an ASP.NET Core 3.1 project with the following structure.

MyApp.Web
  wwwroot
    (css, js folders etc.)
    Resources
      (production files)

I also have an integration test project.

MyApp.Web.IntegrationTests
  Resources
    (test files)

The integration test project contains a test class that extends IClassFixture<WebApplicationFactory<MyApp.Web.Startup>> and has its own Resources folder containing test files.

I would like to keep my test files in the integration test project, and for my web app to reference the integration test Resources folder when running integration tests. Of course, when running the web app normally, the web app should reference its own Resources folder.

What's the best way to achieve this?

3

There are 3 answers

0
Mark Cooper On
0
Deivydas Voroneckis On

Comparing to your web app running normally you can create a slightly different configuration in integration testing. Before passing IConfiguration to your WebHostBuilder configure it as you need.

If you want to use real resources in integration tests I would keep those files in web app project and reference them from integration tests project. As I don't know how you access those files I can't give you full answer but using this configuration it should quite easy to do this

public static IConfiguration CreateConfiguration()
{
    var currentDirectory = Directory.GetCurrentDirectory();
    string appsettingsPath = Path.GetFullPath(Path.Combine(currentDirectory, @"../../../../WebApp.Api/"));
    var config = new ConfigurationBuilder()
         .AddJsonFile(SettingsFileName, optional: false, reloadOnChange: false)
         .AddJsonFile(Path.Combine(appsettingsPath, "appsettings.json"), optional: false, reloadOnChange: false)
         .AddJsonFile(Path.Combine(appsettingsPath, "appsettings.Development.json"), optional: false, reloadOnChange: false)
         .AddUserSecrets(UserSecretsId)
         .AddEnvironmentVariables()
         .Build();
    return config;
}
var builder = new WebHostBuilder()
       .UseEnvironment("Development")
       .UseConfiguration(configuration)
       .UseStartup<Startup>();
0
fractor On

In the end I substituted a dependency as follows.

public class ReportsIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
    public ReportsIntegrationTests(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }
}

[Fact]
async Task CanGetReport()
{
    var client = _factory.WithWebHostBuilder(
        builder =>
        builder.ConfigureServices(services =>
        {
            services.Remove(services.SingleOrDefault(d => d.ServiceType == typeof(IResourcesPathProvider)));
            services.AddSingleton<IResourcesPathProvider, CustomResourcesPathProvider>();
        })).CreateClient();

    var response = await client.GetAsync("/reports?dataSource=DataSource");

    // Checks and assertions...
}

public class CustomResourcesPathProvider : IResourcesPathProvider
{
    public string ResourcesFolder => "Resources";
}