首页 > 解决方案 > 模拟时,IConfiguration 不断获取空值

问题描述

我可以询问我是否正确地模拟了我的 IConfiguration,因为我一直收到一个空错误。我试图在读取 appsettings.json 的地方模拟我的控制器。

ControllerOne.cs

 private readonly IConfiguration _configuration;
 public Controller(IConfiguration configuration)
 {
     _configuration = configuration;
 }

 [HttpPost("upload")]
 public async Task<IActionResult> UploadFile([FromForm(Name = "files")] List<IFormFile> files, CancellationToken cancellationToken = default)
 {
      string directory = _configuration.GetValue<string>("ShippingService:ServerDirectory");
      string subDirectory = _configuration.GetValue<string>("ShippingService:UploadRateSubDirectory");
 }

控制器测试.cs

public class ControllerTest: ControllerTestsBase<ControllerOne>
{

   [Fact]
   public void TestOne()
   {
       IFormFile file = new FormFile(new MemoryStream(Encoding.UTF8.GetBytes("This is a dummy file")), 0, 0, "Data", "dummy.txt");
       List<IFormFile> formFiles = new List<IFormFile>();
       formFiles.Add(file);
       //when
       await Controller.UploadFile(formFiles, default);
   }
}

ControllerTestsBase.cs

 public abstract class ControllerTestsBase<T>
    where T : ApiControllerBase
{
    protected readonly T Controller;
    protected readonly AutoMocker Mocker;

    protected ControllerTestsBase()
    {
        Mocker = new AutoMocker();

        var httpResponseMock = Mocker.GetMock<HttpResponse>();
        httpResponseMock.Setup(mock => mock.Headers).Returns(new HeaderDictionary());

        var httpRequestMock = Mocker.GetMock<HttpRequest>();

        var httpContextMock = Mocker.GetMock<HttpContext>();
        httpContextMock.Setup(mock => mock.Response).Returns(httpResponseMock.Object);
        httpContextMock.Setup(mock => mock.Request).Returns(httpRequestMock.Object);

        var fakeValues = new Dictionary<string, string>
        {
            {"ShippingService:ServerDirectory", "abc"},
            {"ShippingService:UploadRateSubDirectory", "test.com"}
        };

        IConfiguration config = new ConfigurationBuilder()
            .AddInMemoryCollection(fakeValues)
            .Build();

        Controller = Mocker.CreateInstance<T>();
        Controller.ControllerContext.HttpContext = httpContextMock.Object;
    }
}

当我调试并跟踪到Controller.cs methodOne时,_configuration 一直提示 null 错误。

标签: c#unit-testingasp.net-coreautomocking

解决方案


文档状态:

如果您有需要使用的特殊实例,可以使用 .Use(...) 注册它。这与常规 IoC 容器中的注册非常相似(即 StructureMap 中的 For().Use(x))。

因此我希望这会起作用:

IConfiguration config = new ConfigurationBuilder()
    .AddInMemoryCollection(fakeValues)
    .Build();

Mocker.Use<IConfiguration>(config);

Controller = Mocker.CreateInstance<T>();
Controller.ControllerContext.HttpContext = httpContextMock.Object;

推荐阅读