【问题标题】:Integrated Unit Testing is not running in ASP.NET core MVC/Web API集成单元测试未在 ASP.NET 核心 MVC/Web API 中运行
【发布时间】:2019-02-20 17:47:23
【问题描述】:

我正在使用 ASP.Net 核心开发 Web API。我正在对我的项目进行集成测试。我正在关注这个链接,https://koukia.ca/integration-testing-in-asp-net-core-2-0-51d14ede3968。这是我的代码。

我在 thegoodyard.api 项目中有要测试的控制器。

namespace thegoodyard.api.Controllers
{
   [Produces("application/json")]
   [Route("api/category")]
   public class CategoryController: Controller
   {
      [HttpGet("details/{id}")]
      public string GetCategory(int id = 0)
      {
         return "This is the message: " + id.ToString();
      }
   }
}

我在解决方案中添加了一个名为 thegoodyard.tests 的新单元测试项目。我添加了一个具有以下定义的 TestServerFixture 类

namespace thegoodyard.tests
{
    public class TestServerFixture : IDisposable
    {
      private readonly TestServer _testServer;
      public HttpClient Client { get; }

      public TestServerFixture()
      {
         var builder = new WebHostBuilder()
                .UseContentRoot(GetContentRootPath())
                .UseEnvironment("Development")
                .UseStartup<Startup>();  // Uses Start up class from your API Host project to configure the test server

         _testServer = new TestServer(builder);
         Client = _testServer.CreateClient();
      }

      private string GetContentRootPath()
      {
         var testProjectPath = PlatformServices.Default.Application.ApplicationBasePath;
         var relativePathToHostProject = @"..\..\..\..\..\..\thegoodyard.api";
         return Path.Combine(testProjectPath, relativePathToHostProject);
      }

      public void Dispose()
      {
         Client.Dispose();
         _testServer.Dispose();
      }
   }
}

然后再次在测试项目中,我创建了一个名为 CategoryControllerTests 的新类,其定义如下。

namespace thegoodyard.tests
{
    public class CategoryControllerTests: IClassFixture<TestServerFixture>
   {
      private readonly TestServerFixture _fixture;

      public CategoryControllerTests(TestServerFixture fixture)
      {
         _fixture = fixture;
      }

      [Fact]
      public async Task GetCategoryDetai()
      {
         var response = await _fixture.Client.GetAsync("api/category/details/3");

         response.EnsureSuccessStatusCode();

         var responseString = await response.Content.ReadAsStringAsync();

         bool containMessage = false; //responseString.Contains("This is the message: 3"); - I commented on purpose to make the test fails.
         Assert.True(containMessage);
      }
   }
}

然后我在测试方法上右击并单击选项中的运行测试以运行测试。但是没有运行任何测试。这是输出。

我的代码中缺少什么?如何让我的集成测试运行?

【问题讨论】:

  • 您的 csproj 文件中是否有 Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" 用于测试项目?尝试删除它。如果没有帮助,请检查此stackoverflow.com/questions/35103781/… 以确保尚未解决问题。

标签: unit-testing asp.net-core .net-core


【解决方案1】:

请检查您项目中的以下 NuGet 包:

Microsoft.AspNetCore.TestHost
Microsoft.NET.Test.Sdk
xunit
xunit.runner.visualstudio

【讨论】:

    【解决方案2】:

    可能存在阻止项目编译的构建错误。这里确实没有足够的信息可以肯定地说。重建您的解决方案,并确保没有错误。

    除此之外,您还可以通过减少所需的测试代码来删除一些变量。 ASP.NET Core 包含一个开箱即用的 WebApplicationFactory&lt;TEntryPoint&gt; 固定装置,用于引导测试服务器。因此,您可以将测试代码更改为:

    public class CategoryControllerTests: IClassFixture<WebApplicationFactory<Startup>>
    {
        private readonly WebApplicationFactory<Startup> _factory;
    
        public CategoryControllerTests(WebApplicationFactory<Startup> factory)
        {
            _factory = factory;
        }
    
        [Fact]
        public async Task GetCategoryDetail()
        {
            var client = _factory.CreateClient();
            var response = await client.GetAsync("api/category/details/3");
            ...
    

    请参阅documentation 了解更多信息和更高级的方案。

    【讨论】:

      【解决方案3】:

      这种方式适用于基于 xUnit 的集成测试,它使用 Startup 配置。该代码还演示了如何将appSetting.json 中的某些设置覆盖为特定值进行测试,以及如何访问DI 服务。

      using System;
      using System.Net.Http;
      using MyNamespace.Web;
      using MyNamespace.Services;
      using Microsoft.AspNetCore;
      using Microsoft.AspNetCore.Hosting;
      using Microsoft.AspNetCore.TestHost;
      using Microsoft.Extensions.Configuration;
      using Microsoft.Extensions.Logging;
      
      namespace MyNamespace.Tests
      {
          public class TestServerDependent : IDisposable
          {
              private readonly TestServerFixture _fixture;
              public TestServer TestServer => _fixture.Server;
              public HttpClient Client => _fixture.Client;
      
              public TestServerDependent()
              {
                  _fixture = new TestServerFixture();
      
                  var myService = GetService<IMyService>();
                  // myService.PerformAnyPreparationsForTests();
              }
      
              protected TService GetService<TService>()
                  where TService : class
              {
                  return _fixture.GetService<TService>();
              }
      
              public void Dispose()
              {
                  _fixture?.Dispose();
              }
          }
      
          public class TestServerFixture : IDisposable
          {
              public TestServer Server { get; }
              public HttpClient Client { get; }
      
              public TestServerFixture()
              {
                  var hostBuilder = WebHost.CreateDefaultBuilder()
                      .ConfigureAppConfiguration(
                          (builderContext, config) =>
                          {
                              var env = builderContext.HostingEnvironment;
                              config
                                  .AddJsonFile("appsettings.json", optional: false)
                                  .AddJsonFile("appsettings.Testing.json", optional: false,
                                      reloadOnChange: true);
                          })
                      .ConfigureLogging(
                          (hostingContext, logging) =>
                          {
                              logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                              logging.AddConsole();
                              logging.AddDebug();
                          })
                      .UseStartup<Startup>();
      
                  Server = new TestServer(hostBuilder);
                  Client = Server.CreateClient();
              }
      
              public void Dispose()
              {
                  Server.Dispose();
                  Client.Dispose();
              }
      
              public TService GetService<TService>()
                  where TService : class
              {
                  return Server?.Host?.Services?.GetService(typeof(TService)) as TService;
              }
          }
      }
      

      简单的集成测试看起来像上面描述的那样:

      using System.Net;
      using Xunit;
      
      namespace MyNamespace.Tests
      {
          public class SimpleIntegrationTest : TestServerDependent
          {
              [Fact]
              public void RedirectToLoginPage()
              {
                  var httpResponseMessage = Client.GetAsync("/").Result;
      
                  // Smoke test to make sure you are redirected (to Login page for instance)
                  Assert.Equal(HttpStatusCode.Redirect, httpResponseMessage.StatusCode);
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        • 2020-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多