如何在 nunit dotnet 核心测试项目中使用 appsettings?

How to use appsettings in nunit dotnet core test project?

我已经成功地从 appsettings.json 文件中将 AppSettings 添加到我的 Api 项目中

Startup.cs 在 ConfigureServices() 函数中

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

我的post函数

    [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 控制器来测试它。这样,您应该创建 UserProfilesController 并传递一个模拟的 appSettings 对象。

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

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

由于我使用的是 Development 环境,因此我的测试项目中还需要一个 appsettings.Development.json 文件。

然后,您可以像这样使用您创建的内存服务器:

testServer.CreateClient().PostAsync(string requestUri, HttpContent content)

编辑:

TestServer 来自 Microsoft 软件包:

"Microsoft.AspNetCore.TestHost": "1.0.0"

因此,它应该可以与 nUnit 一起正常工作。

您看到的问题是使用 MyTested 模拟框架造成的。它为控制器的依赖项(IOptions<AppSettings> 实例)创建了一个具有模拟值的控制器。此模拟将为任何未专门配置的 属性 return 默认(空)值。

如果这是一个单元测试,您实际上不想通过使用 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()
}