当前位置: 首页 > 知识库问答 >
问题:

集成单元测试没有在ASP.NET核心MVC/Web API中运行

曹子平
2023-03-14

我正在使用ASP.Net核心开发一个网络应用编程接口。我正在对我的项目进行集成测试。我点击这个链接,https://koukia.ca/integration-testing-in-asp-net-core-2-0-51d14ede3968.这是我的代码。

我有控制器要在古德.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();
      }
   }
}

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

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

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

共有3个答案

郭阳曜
2023-03-14

这种方式适用于使用启动配置的基于 xUnit 的集成测试。代码打击还演示了如何将 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);
        }
    }
}
微生令雪
2023-03-14

也许存在阻止编译项目的生成错误。这里真的没有足够的信息可以肯定地说。重新生成解决方案,并确保没有错误。

除此之外,您可以通过减少所需的测试代码来删除一些变量。ASP.NET核心包括一个WebApplication ationFactory

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

有关其他信息和更高级方案,请参阅文档。

司马彬
2023-03-14

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

Microsoft.AspNetCore.TestHost
Microsoft.NET.Test.Sdk
xunit
xunit.runner.visualstudio
 类似资料:
  • 在我的asp.net核心项目(与2017年相比)中,我想运行我的测试方法,但在测试资源管理器中单击“运行所有”,我在测试资源管理器控制台中得到“最后一次测试运行不运行(总运行时间“布拉布拉”)”响应。我已经下载了我的NunitNuGet包。我认为在我的启动类或其他地方asp.net核心中测试有一些缺失的测试配置,或者一些缺失的NuGet包:/Thx提前给每个人。 这是我的测试课: 下面是我的“Gu

  • 单元测试 单元测试仅依赖于源代码,是测试代码逻辑是否符合预期的最简单方法。 运行所有的单元测试 make test 仅测试指定的package # 单个package make test WHAT=./pkg/api # 多个packages make test WHAT=./pkg/{api,kubelet} 或者,也可以直接用go test go test -v k8s.io/kubernet

  • 我正在尝试将ASP.NET MVC webform迁移到ASP.NET核心MVC。当前,类遇到问题。 原来的行是: 但是,对于ASP.NET核心,UrlReferrer不可用。我发现了以下内容: 它返回StringValues而不是String。我不确定我是否应该尝试使用这一个,或者是否有任何其他解决办法来解决这种情况。也不可用,或者我没有该命名空间。我的命名空间如下: 如果有人能指引我正确的方向

  • .NET核心和ASP.NET核心到底有什么区别?

  • 在ASP.NET MVC5中,您可以抛出一个带有HTTP代码的HttpException,这将设置如下所示的响应: ASP.NET核心中不存在。等价代码是什么?

  • 如何在ASP.NET Core2.1项目中设置swagger属性?根据这篇文章,我应该使用,但我在swashbuckle.aspnetcore库中找不到它。还有 而且我找不到任何用于大摇大摆生成目的的实现。