1

May I enquire if I am mocking my IConfiguration correctly as I keep get a null error. I am trying to mock my controller where it reads the 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");
 }

ControllerTest.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;
    }
}

When I debug and trace to the Controller.cs methodOne, the _configuration keeps prompted null error.

  • Apologies for the snippet of code, I have updated the code again.
  • I have also realized that my previous post here c# Mock IConfiguration keeps get null is being closed as I have previously posted something that couldn't compile.
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
rosepalette
  • 186
  • 2
  • 19
  • You care creating `IConfiguration config` object but not passing to Controller constructor. – Chetan Jul 01 '20 at 00:42
  • You need to create Controller object in test with configuration passed to it and then call UploadFile method on it. – Chetan Jul 01 '20 at 00:43
  • `IConfiguration config = new ConfigurationBuilder() .AddInMemoryCollection(mockValue) .Build();` <--- you have configured your configuration and then... you're not using it . How your controller should know about this configuration? Your should pass this config to controller's constructor – Roman Kalinchuk Jul 01 '20 at 01:19
  • My bad about that. I am using AutoMocker to initialize the Controller. I couldn't find anyway for me to pass over the config when I mock the Controller with AutoMocker. `Controller = Mocker.CreateInstance();` Is there any way that I can pass the configuration? – rosepalette Jul 01 '20 at 01:49

1 Answers1

1

The docs state:

If you have a special instance that you need to use, you can register it with .Use(...). This is very similar to registrations in a regular IoC container (i.e. For().Use(x) in StructureMap).

Therefore I expect this would work:

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

Mocker.Use<IConfiguration>(config);

Controller = Mocker.CreateInstance<T>();
Controller.ControllerContext.HttpContext = httpContextMock.Object;
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86