61

I have an ASP.NET Core Web API project targeting .NET Framework 4.7 that I'm trying to write integration tests for. I created a unit test project using Visual Studio Add new project and then the Unit Test Project (.NET Framework) template. I added the Microsoft.AspNetCore.Mvc.Testing NuGet package to the test project, and I have the following test:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestRepro.Tests
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public async Task TestMethod1()
        {
            var factory = new WebApplicationFactory<Startup>();
            var client = factory.CreateClient();
            var response = await client.GetAsync("/api/values");
        }
    }
}

But this throws the following exception:

Test method TestRepro.Tests.UnitTest1.TestMethod1 threw exception: System.InvalidOperationException: Can't find'[path removed]\TestRepro.Tests\bin\Debug\TestRepro.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 '<PreserveCompilationContext>true</PreserveCompilationContext>'. For functional tests to work they need to either run from the build output folder or the TestRepro.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 have verified that TestRepro.deps.json exists in the web application output folder (TestRepro\bin\Debug\net47), but it is not copied to the test project output folder (TestRepro.Tests\bin\Debug). And I have not been able to find out how to disable shadow copying.

Edit: The documentation says:

The Microsoft.AspNetCore.Mvc.Testing package handles the following tasks: Copies the dependencies file (*.deps) from the SUT into the test project's bin folder.

But that doesn't seem to work. I can copy the file manually, but that doesn't work in an automated build scenario. One way would be to have a build step doing it in TeamCity, but it feels crude. Any ideas?

I have a repro on GitHub if that helps.

10 Answers 10

128

We should get "Program" class from the main project but it automatically references Microsoft.AspNetCore.Mvc.Testing.Program class

public class VersioningTests : IClassFixture<WebApplicationFactory<Program>>

this code must reference our main Program code. So we must put a reference to the Program class on the last line in Program.cs file:

public partial class Program { }
Sign up to request clarification or add additional context in comments.

5 Comments

There is an example project in Github by Damian Edward about Integration/Unit Tests in .NET 6 with minimal API and he makes the Program class public. Reference her github.com/DamianEdwards/MinimalApiPlayground/blob/main/src/…
Better variant: add visibility to internal Program for test project with [assembly: InternalsVisibleTo("IntegrationTests")] , and Program don't make public,
I needed to unload and reload my Testproject and then restart Visual Studio before it started using the correct Program reference.
@Ahmet Arslan I want to thank you! This was helpful.
I think adding "public partial class Program { }" at the end after the app.Run() line worked for me. Now I get an error in my test on a Times.Once() statement, but at least I think it is working now. Thank you.
46

I just ran into this same issue and found the root cause to be quite obscure. From the documentation, the .deps files should be copied to the integration test project's bin directory. This wasn't happening for me because was not explicitly referencing the Microsoft.AspNetCore.Mvc.Testing package from my integration test project. I had created a shared library with some utility functions that referenced that nuget package, so my integration test project indirectly referenced it.

There's some custom build tasks in the Microsoft.AspNetCore.Mvc.Testing package that copy the referenced service deps.json files for you, so you must reference it directly from the integration test project in order to get those build tasks to run.

2 Comments

If you run into the same problem as listed above and using .net core, the solution described in this answer is extactly what you need. I had forgotten this aswell in my integration test project.. Thanks alot for your answer @TylerOhlsen.
This was the solution for me too. Tests were working until I'd created a shared library and refactored out duplicate dependencies. The unit tests project must reference Microsoft.AspNetCore.Mvc.Test for the voodoo with deps.json to take place.
46

Okay, after almost two hours of trying to solve this... I got it.

My issue was I was using the new .NET6 Minimal APIs Program.cs format which does not have Program class (nor a namespace) defined and I was literally referencing the wrong class in the WebApplicationFactory<Program> definition... it came from Microsoft.VisualStudio.TestPlatform.TestHost (seriously WTF), so what you need to do is:

  1. Use your own actual Program.cs, so you add a namespace to your Minimal APIs Program.cs file and create an actual Program class with a Main method.
  2. Now you can reference the proper Program class as the generic type for the WebApplicationFactory
  3. Make sure you make internals visible in the web app project so you can expose the Program class (if you marked it internal).

This is basically an additon to Ahmets answer here: https://stackoverflow.com/a/70490057/1534753

6 Comments

Upvote for visibility, this was my case also
This was my problem as well.. I'm seriously considering turning off automatically adding using statements. Thanks!
Up vote, this is literally what just happened to me
my case as well
This helped me understand the answer by @Ahmet Arslan above. I just put the following line at the end of Program.cs public partial class Program { }
|
17

Follow steps below to create Integration Test for Asp.Net Core with targeting net 47.

  1. Create New Project-> xUnit Test Project(.Net Core)
  2. Right click new project->Edit .csproj->Change TargetFramework to net47
  3. Add Project Reference to TestRepro
  4. Install-Package Microsoft.AspNetCore.Mvc.Testing
  5. Add Test file like below

    public class BasicTests
    : IClassFixture<WebApplicationFactory<Startup>>
    {
        private readonly WebApplicationFactory<Startup> _factory;
    
        public BasicTests(WebApplicationFactory<Startup> factory)
        {
            _factory = factory;
        }
    
        [Fact]
        public async Task TestMethod1()
        {
            var client = _factory.CreateClient();
            var response = await client.GetAsync("/api/values");
        }
    
    }
    
  6. Run Test Project

7 Comments

Yes, that actually works! But I don't understand why. Is it because it started out as a .NET Core project and then was re-targeted? Or is it becuase it is using xUnit rather than MSTest framework?
@HenrikOlsson I assume it is related with MSTest. For the doc, it is used with xunit test.
No it's not - I just tried creating a MSTest project the same way, as in your answer, and that worked as well. So my conclusion is that you have to begin with target .Net Core and then change target.
This didnt fix my issue when I want to target .net core. What should I do?
@SamuelJ does my answer fix your issue?
|
6

For those trying to do Integration testing from unit testing on a minimal API setup (e.g.):

[TestMethod]
public void Test()
{
    var application = new WebApplicationFactory<Program>().WithWebHostBuilder(builder =>{});
    var body = JsonSerializer.Serialize(request);
    var content = new StringContent(body, Encoding.UTF8, "application/json");
    var client = application.CreateClient();

    var response = client.PostAsync("myendpoint", content).Result;
}

You can expose the application Program (class) to the unit testing adding a Program partial class as follow(e.g. Program.UnitTests.cs):

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("UnitTests")]

namespace API;

partial class Program {}

It took me a while to get a right solution for the minimal API setup, so I hope this avoid others to waste much time looking for a solution as I did. I obtained this from the following source (in case you need more information): How to test minimal APIs in ASP.NET Core 6

1 Comment

This answer goes well with the other by @Vedran Mandić. Between the two I was able to figure it out.
6

I've had the same error message.

Try to add the project reference to the SUT project (the project that I want to test).

Project Referance in the solution explorer

1 Comment

Great answer, considering now days a lot of devs are using new concepts, separated layers, decoupled projects, when you build the test project for the API, it is common that you don't have to import anything from de API by itself, so we forget about this reference.
5

For me, I already had a reference to Microsoft.AspNetCore.Mvc.Test in my test project, but removing the following fixed the issue:

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

1 Comment

This essentially fixed it for me when upgrading to .NET 5.0, which is strange. But I have a shared assembly info so I removed that line and replaced it with: <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute> <GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute> <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
1

Accepted answer assumes that deps.json file exists in your project bin folder, so it can be copied into integration test bin folder.
In my case deps.json file was missing in application bin folder. In this case make sure you have

<PreserveCompilationContext>true</PreserveCompilationContext>

in your csproj file.

Comments

0

I'm facing the same issue and I want to share with you a way to make it copy to publish below:

Find the .csprj test file Add the following code would help you get through.

p/s I'm using .net core 3.1, so it would be useful for .net core test prj.

   <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <IsPackable>false</IsPackable>
      </PropertyGroup>
     <Target Name="CopyDepsJsonFiles" AfterTargets="Publish">
            <ItemGroup>
              <DepsJsonFiles Include="$(TargetDir)*.deps.json" />
            </ItemGroup>
            <Copy SourceFiles="@(DepsJsonFiles)" DestinationFolder="$(PublishDir)" />
        </Target>
<!-- ... other elements-->
    </Project>

Comments

0

My app's target framework is net8.0-windows and it uses minimal API. Adding this to the main app project file resolved the exception described by the OP:

  <ItemGroup>
    <InternalsVisibleTo Include="ScaAutomation.IntegrationTests" />
  </ItemGroup>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.