如何在网络核心测试项目中使用应用程序

本文关键字:应用程序 项目 测试 网络 核心 | 更新日期: 2023-09-27 18:13:22

我已经设法从appsettings.json文件中添加AppSettings在我的Api项目中,像这样

ConfigureServices()函数中的Startup.cs

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

Controller.cs

private readonly AppSettings _AppSettings;
public UserProfilesController(IOptions<AppSettings> appSettings)
{
   _AppSettings = appSettings.Value;
}

但是我不知道如何为我的测试项目做到这一点。我的测试项目中没有Startup.ts。那么,如何在测试项目中以同样的方式添加应用程序呢?

编辑:

单单元测试

    [Test]
    public void Post_Should_Create_A_Single_UserProfile()
    {
        // Arrange
        var profile = Dummy.GenerateCreateUserProfileDto();
        MyMvc
        .Controller<UserProfilesController>()
        .Calling(c => c.Post(profile))
        .ShouldReturn()
        .Ok()
        .WithResponseModelOfType<UserProfileDto>()
        .Passing(target =>
        {
            target.Should().NotBeNull(because: "a record is expected here");
            target.Id.Should().BeGreaterThan(0, because: "a id is expected");
            target.ShouldBeEquivalentTo(profile, opt => opt
                .Excluding(c => c.Id)
                .Excluding(c => c.CreatedOn)
                .Excluding(c => c.ModifiedOn),
                because: "the record returned is expected to be the same as the record inserted");
            // Clean up
            _Repo.Delete(target.Id);
        });
    }

My post function

    [HttpPost]
    public async Task<IActionResult> Post([FromBody]CreateUserProfileDto profile)
    {
        using (var fileManager = new FileManager())
        using (var manager = new UserProfilesRepository())
        {
            var mapped = Mapper.Map<UserProfile>(profile);
            // Only save the profile image if one is selected
            if (!string.IsNullOrEmpty(profile.Image))
            {
                try
                {
                    var result = fileManager.SaveProfileImage(
                        profile.Image,
                        _AppSettings.Profile.AbsolutePath,
                        _AppSettings.BaseUrl,
                        _AppSettings.Profile.RelativePath
                    );
                    mapped.FilePath = result.AbsolutePath;
                    mapped.ProfilePicture = result.RelativePath;
                }
                catch (Exception ex)
                {
                    return StatusCode(500);
                }
            }
            manager.Save(mapped);
            return Ok(Mapper.Map<UserProfileDto>(mapped));
        }
    }

如何在网络核心测试项目中使用应用程序

您正在模拟MVC控制器来测试它。这样,您应该通过模拟的appSettings对象创建UserProfilesController

另一个选项是启动应用程序,使用Startup.cs类对其进行测试。我从未使用过nUnit,但在xUnit中,我像这样配置我的测试项目:

TestServer testServer = new TestServer(new WebHostBuilder().UseEnvironment("Development").UseStartup<Startup>());

由于我使用的是Development环境,所以我还需要在我的测试项目中使用appsettings.Development.json文件。

然后,您可以像这样使用您创建的内存服务器:
testServer.CreateClient().PostAsync(string requestUri, HttpContent content)
编辑:

TestServer from Microsoft package:

"Microsoft.AspNetCore.TestHost": "1.0.0"

所以,它应该可以很好地与nUnit一起工作。

您看到的问题是使用mytesting模拟框架的产物。它为控制器的依赖项(IOptions<AppSettings>实例)创建一个带有模拟值的控制器。这个模拟将返回没有特别配置的任何属性的默认(空)值。

如果这是一个单元测试,你实际上不希望通过使用ConfigurationBuilder等从appsettings加载来测试它。相反,您应该在测试中提供AppSettings对象作为依赖项,并显式定义值。

MyTested.AspNetCore.Mvc

using MyTested.AspNetCore.Mvc.DependencyInjection;
[Test]
public void Post_Should_Create_A_Single_UserProfile()
{
    // Arrange
    var profile = Dummy.GenerateCreateUserProfileDto();
    MyMvc
    .Controller<UserProfilesController>()
    .WithOptions(options => options
        .For<AppSettings>(settings => settings.Cache = true))
    .Calling(c => c.Post(profile))
    .ShouldReturn()
    .Ok()
}

原始答案:MyTested。WebApi

例如,你可以这样做:

using Microsoft.Extensions.Options;
[Test]
public void Post_Should_Create_A_Single_UserProfile()
{
    // Arrange
    var profile = Dummy.GenerateCreateUserProfileDto();
    var mockedSettings = new AppSettings
    {
         MyValue = "the test value"
    }
    MyMvc
    .Controller<UserProfilesController>()
    .WithResolvedDependencyFor<IOptions<AppSettings>>(Options.Create(mockedSettings))
    .Calling(c => c.Post(profile))
    .ShouldReturn()
    .Ok()
}