.NET Framework 的集成测试 ASP.NET Core - 找不到 deps.json

Integration testing ASP.NET Core with .NET Framework - can't find deps.json

我有一个针对 .NET Framework 4.7 的 ASP.NET Core Web API 项目,我正在尝试为其编写集成测试。我使用 Visual Studio 添加新项目然后使用单元测试项目 (.NET Framework) 模板创建了一个单元测试项目。我将Microsoft.AspNetCore.Mvc.Testing NuGet包添加到测试项目中,我有以下测试:

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");
        }
    }
}

但这会引发以下异常:

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 'true'. 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.

我已验证 Web 应用程序输出文件夹 (TestRepro\bin\Debug\net47) 中存在 TestRepro.deps.json,但未将其复制到测试项目输出文件夹 (TestRepro.Tests\bin\Debug)。而且我还没有找到如何禁用卷影复制的方法。

编辑: The documentation 说:

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.

但这似乎不起作用。我可以手动复制文件,但这在自动构建场景中不起作用。一种方法是在 TeamCity 中执行构建步骤,但感觉很粗糙。有什么想法吗?

如果有帮助,我有a repro on GitHub

按照以下步骤为目标网络 47 的 Asp.Net 核心创建集成测试。

  1. 创建New Project-> xUnit Test Project(.Net Core)
  2. 右键新建项目->编辑.csproj->将TargetFramework改为net47
  3. 将项目引用添加到 TestRepro
  4. 安装包Microsoft.AspNetCore.Mvc.Testing
  5. 添加如下测试文件

    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. 运行 测试项目

我只是 运行 遇到了同样的问题,发现根本原因非常模糊。从 the documentation 开始,.deps 文件 应该 复制到集成测试项目的 bin 目录。这对我来说并没有发生,因为没有 明确地 从我的集成测试项目中引用 Microsoft.AspNetCore.Mvc.Testing 包。我创建了一个共享库,其中包含一些引用该 nuget 包的实用函数,因此我的集成测试项目间接引用了它。

Microsoft.AspNetCore.Mvc.Testing 包中有一些自定义构建任务会为您复制引用的服务 deps.json 文件,因此您必须 直接从集成测试项目,以便将这些构建任务分配给 运行。

对我来说,我已经在我的测试项目中引用了 Microsoft.AspNetCore.Mvc.Test,但删除以下内容解决了问题:

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

接受的答案假定 deps.json 文件存在于您的项目 bin 文件夹中,因此可以将其复制到集成测试 bin 文件夹中。
在我的例子中,应用程序 bin 文件夹中缺少 deps.json 文件。 在这种情况下,请确保您有

<PreserveCompilationContext>true</PreserveCompilationContext>

在您的 csproj 文件中。

我也遇到了同样的问题,想和大家分享一下复制发布的方法:

找到.csprj 测试文件 添加以下代码将帮助您通过。

p/s我用的是.net core 3.1,所以对.net core测试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>

我在 .NET Core 6 中进行集成测试时遇到了同样的错误。

为了集成,我们应该从主项目中获取“程序”class,但它会自动引用 Microsoft.AspNetCore.Mvc.Testing.Program class

public class VersioningTests : IClassFixture<WebApplicationFactory<Program>>

此代码必须引用我们的主要程序代码。所以我们必须将程序 class 的引用放在 Program.cs 文件的最后一行:

public partial class Program { }

好的,在尝试解决这个问题将近两个小时后...我明白了。

我的问题是我使用的是新的 .NET6 Minimal APIs Program.cs 格式,它没有定义程序 class(也没有命名空间),而且我确实引用了错误的 class 在 WebApplicationFactory<Program> 定义中......它来自 Microsoft.VisualStudio.TestPlatfrom.TestHost(严重的 WTF),所以你需要做的是:

  1. 您需要做的是使用您自己的实际 Program.cs,因此您将命名空间添加到您的 Minimal APIs Program.cs 文件并使用 Main 方法创建一个实际的程序 class .
  2. 现在您可以引用适当的程序 class 作为 WebApplicationFactory
  3. 的通用类型
  4. 确保在 Web 应用程序项目中显示内部结构,以便可以公开程序 class(如果将其标记为内部)。

这基本上是对此处 Ahmets 回答的补充: