Forum

PureSourceCode.com Forum
Share:
Notifications
Clear all

Minimal APIs NUnit test: missing testhost.deps.json

1 Posts
1 Users
0 Likes
5,610 Views
(@enrico)
Member Admin
Joined: 4 years ago
Posts: 151
Topic starter  

In my .NET6 project, I have some minimal APIs and I want to test them. For that, I created a new NUnit test project. In the project file, I added PreserveCompilationContext and the file looks like

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>

    <IsPackable>false</IsPackable>
    <PreserveCompilationContext>true</PreserveCompilationContext>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.1" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
    <PackageReference Include="NUnit" Version="3.13.2" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.2.0" />
    <PackageReference Include="coverlet.collector" Version="3.1.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\src\MinimalApis.csproj" />
  </ItemGroup>

</Project>

Then, I created an implementation of WebApplicationFactory like that

class MinimalApisApplication : WebApplicationFactory<Program>
{
    protected override IHost CreateHost(IHostBuilder builder)
    {
        var root = new InMemoryDatabaseRoot();

        builder.ConfigureServices(services =>
        {
            services.RemoveAll(typeof(DbContextOptions<ClientContext>));
            services.AddDbContext<ClientContext>(options =>
                options.UseInMemoryDatabase("Testing", root));
        });

        return base.CreateHost(builder);
    }
}

Finally, my test class is like that

public class Tests
{
    [SetUp]
    public void Setup()
    {
    }

    [Test]
    public async Task GetClients()
    {
        await using var application = new MinimalApisApplication();

        var client = application.CreateClient();
        var notes = await client.GetFromJsonAsync<List<ClientModel>>("/clients");

        Assert.IsNotNull(notes);
        Assert.IsTrue(notes.Count == 0);
    }
}

When I run the project, I receive an error

System.InvalidOperationException : Can't find 'C:\Projects\Net6MinimalAPIs\MinimalApis.Tests\bin\Debug\net6.0\testhost.deps.json'. This file is required for functional tests to run properly. There should be a copy of the file on your source project bin folder. If that is not the case, make sure that the property PreserveCompilationContext is set to true on your project file. E.g 'true'. For functional tests to work they need to either run from the build output folder or the testhost.deps.json file from your application's output directory must be copied to the folder where the tests are running on. A common cause for this error is having shadow copying enabled when the tests run.

I googled a bit but I can't find how to generate this file.


   
Quote
(@enrico)
Member Admin
Joined: 4 years ago
Posts: 151
Topic starter  

Update

I tried to add a xUnit project with the same result. Also, I noticed that Program is coming from

using Microsoft.VisualStudio.TestPlatform.TestHost;

because I added this reference but this is wrong. I want to refer to the Program in the main project but it is unaccessbile due to its protection level. The Program.cs looks

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<ClientContext>(opt => 
  opt.UseInMemoryDatabase("Clients"));
builder.Services
  .AddTransient<IClientRepository,
                ClientRepository>();
builder.Services
  .AddAutoMapper(Assembly.GetEntryAssembly());

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { 
        Title = builder.Environment.ApplicationName, Version = "v1" 
    });
});

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("v1/swagger.json", 
        $"{builder.Environment.ApplicationName} v1");
});

app.MapFallback(() => Results.Redirect("/swagger"));

// Get a shared logger object
var loggerFactory =
  app.Services.GetService<ILoggerFactory>();
var logger =
  loggerFactory?.CreateLogger<Program>();

if (logger == null)
{
    throw new InvalidOperationException(
      "Logger not found");
}

// Get the Automapper, we can share this too
var mapper = app.Services.GetService<IMapper>();
if (mapper == null)
{
    throw new InvalidOperationException(
      "Mapper not found");
}

   
ReplyQuote
Share: