Home > Back-end >  How to initializate my IDbConnection and IConfiguration with Mock
How to initializate my IDbConnection and IConfiguration with Mock

Time:10-26

I'm wandering how to do this since It gives me nullreferenceexception. I have this constructor on my handler class:

        IDbConnection _dbConnection;
        Context _context;
        SigSettings _settings;
        public SignalsHandler(IConfiguration configuration, IDbConnection connection)
        {
            _dbConnection = connection;
            _settings = configuration.GetSection("SigSettings").Get<SigSettings>();
            if (_settings == null)
                _settings = new SigSettings();
        }

And I want to do unit test about this class to test my crud methods but the code below doesn't work:

private Mock<IConfiguration> _configuration = new Mock<IConfiguration>();
        private Mock<IDbConnection> _connection = new Mock<IDbConnection>();
        private readonly SignalsHandler _handler;

        public SignalsTest()
        {
            _handler = new SignalsHandler(_configuration.Object, _connection.Object);
        }

It gives me this error: System.ArgumentNullException: 'Value cannot be null. Arg_ParamName_Name' on this line: _settings = configuration.GetSection("SigSettings").Get();

Any help?

CodePudding user response:

_configuration is just mocked object and you also need to setup methods it has, otherwise, they will return null, so configuration.GetSection("SigSettings") would return null.

To avoid that, you need to write:

_configuration
   .Setup(x => x.GetSection("SigSettings"))
   .Returns("some setting");

or more generally:

_configuration
   .Setup(x => x.GetSection(It.IsAny<string>()))
   .Returns("some setting");

UPDATE

As I did not realize that methods returns some object rather than string, here's full setup. Generally you always provide mocks for all the way of method calls, so nowhere you will get null:

var configSectionMock = new Mock<IConfigurationSection>();
var configMock = new Mock<IConfiguration>();
configMock
    .Setup(x => x.GetSection(It.IsAny<string>()))
    .Returns(configSectionMock.Object);

// Instantiate system under test with mocked object.
var sut = new Sut(configMock.Object);

CodePudding user response:

Alternative approach not to mock IConfiguration, but provide actual implementation which provides useful feedback without coupling to the methods used in the class under the test.

var configuration = new ConfigurationBuilder()
    .AddInMemoryCollection(new[] 
    { 
        new KeyValuePair<string, string>("SigSettings:One", "value1"),
        new KeyValuePair<string, string>("SigSettings:Two", "value2"),
    })
    .Build();

var sut = new Sut(configuration);

Now in the Sut you can use different ways to access configuration values without rewriting tests.

  • Related