Moq 和 xUnit 的单元测试失败 - InvalidOperationException

Unit Test Failing with Moq and xUnit - InvalidOperationException

我正在按照这篇文章使用 Moq 和 Xunit 设置一个简单的集成测试:https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/testing?view=aspnetcore-3.1

当我 运行 测试时出现以下错误:

System.InvalidOperationException : Can't load type x.IntegrationTests.Startup in 'x.IntegrationTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

HomeControllerTests.cs

public class HomeControllerTests
    {
        [Fact]
        public void Test()
        {
            Assert.True(true);
        }
    }

csproj

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

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.1.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
    <PackageReference Include="Moq" Version="4.15.2" />
    <PackageReference Include="xunit" Version="2.4.1" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="coverlet.collector" Version="1.3.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\x\x.csproj" />
  </ItemGroup>

  <ItemGroup>
    <None Update="xunit.runner.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

我发现将我的最小起订量服务转移到测试装置上很有效。希望下面的松散示例可以为您提供一些有用的东西...

夹具:

public class MyTestServicesFixture
{
    public MyTestServicesFixture()
    {
        var services = new ServiceCollection();

        ...

        var mockDataService = new Mock<IPhotoCollectionDataService>();
        mockDataService.Setup(s => s.GetPhotoAsync((int)TestPhotoIds.TestJpegImage))
            .ReturnsAsync(() =>
            {
                return BuildTestPhotoEntity(TestPhotoIds.TestJpegImage, "example.jpg");
            }
            );
        mockDataService.Setup(s => s.GetPhotoAsync((int)TestPhotoIds.TestHeifStillImage))
            .ReturnsAsync(() => 
            {
                return BuildTestPhotoEntity(TestPhotoIds.TestHeifStillImage, "example.heic");
            }
            );
        services.AddScoped(sp => mockDataService.Object);

        ...

        ServiceProvider = services.BuildServiceProvider();
    }

    public ServiceProvider ServiceProvider { get; private set; }

    private Photo BuildTestPhotoEntity(TestPhotoIds testPhotoId, string fileName)
    {
        return new Photo
        {
            Id = (int)testPhotoId,
            PhotoCollectionId = TestSettings.TEST_PHOTO_COLLECTION_ID,
            OriginalFileName = fileName,
            UploadFileName = fileName,
            Description = $"Test description for {fileName}"
        };
    }
}

使用夹具进行测试:

public class PhotoCollectionServiceTests : IClassFixture<MyTestServicesFixture>
{
    protected readonly IPhotoCollectionDataService _photoCollectionDataService;

    public PhotoCollectionServiceTests(MyTestServicesFixture testsFixture)
    {
        var services = testsFixture.ServiceProvider;
        _photoCollectionDataService = services.GetRequiredService<IPhotoCollectionDataService>();
    }

    [Theory]
    [InlineData(TestPhotoIds.TestJpegImage)]
    [InlineData(TestPhotoIds.TestHeifStillImage)]
    public async Task ProcessPhotoUploadTest(TestPhotoIds testPhotoId)
    {
        // Arrange

        ...

        // Act

        var result = _photoCollectionDataService.DoSomething(testPhotoId);

        // Assert

        ...

    }
}