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

时间:2016-10-17 19:10:05

标签: c# .net asp.net-core nunit appsettings

我设法从appsettings.json文件中添加了我的Api项目中的AppSettings

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。那么如何在我的测试项目中以相同的方式添加appsettings?

编辑:

一次nunit测试

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

我的帖子功能

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

2 个答案:

答案 0 :(得分:2)

你正在嘲笑你的MVC控制器来测试它。这样,您应该创建UserProfilesController传递模拟的appSettings对象。

另一种选择是启动应用程序以使用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来自Microsoft软件包:

"Microsoft.AspNetCore.TestHost": "1.0.0"

因此,它应该可以正常使用nUnit。

答案 1 :(得分:2)

您看到的问题是使用MyTested模拟框架的假象。它创建一个控制器,其中包含控制器依赖关系的模拟值(IOptions<AppSettings>实例)。此mock将返回尚未专门配置的任何属性的默认值(null)。

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