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.