1

I'm trying to do unit testing to my handler database but I got a nullReferenceException when I call my methods.

This is my handler constructor

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

And what I do is to Mock that with this on my testing class:

private Mock<IConfigurationSection> _configSectionMock = new Mock<IConfigurationSection>();
private Mock<IConfiguration> _configMock = new Mock<IConfiguration>();
private Mock<IDbConnection> _connection = new Mock<IDbConnection>();
private readonly SignalsHandler _handler;

public SignalsTest()
{
    _configMock.Setup(x => x.GetSection(It.IsAny<string>())).Returns(_configSectionMock.Object);
    _handler = new SignalsHandler(_configMock.Object, _connection.Object);
}

So far so good but when I try to implement some testing it doesn't work. For example, a simple test:

public void CanGetAllSignals()
{
    var result = _handler.GetSignals();
    Assert.IsNotNull(result);
}

I call my .GetSignals() method with my Mock handler. This is the code:

public async Task<List<SignalsDTO>> GetSignals()
{
    var res = new List<SignalsDTO>();
    var sigList = await _dbConnection.QueryAsync<SigSignal>(_settings.Signals);
    foreach (var s in sigList)
        res.Add(new SignalsDTO()
        {
            IDTag = s.IDTag,
            Name = s.Name
        });
    return res;
}

But when I debug my testing method I got:
NullReferenceException:'Object reference not set to an instance of an object.'
at this line:

var sigList = await _dbConnection.QueryAsync<SigSignal>(_settings.Signals);

I suppose this is an error with my mock configuration at my test constructor but I'm not sure about how can I fix this.

MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46
Weenhallo
  • 324
  • 2
  • 8

1 Answers1

2

You forgot to setup a return object of a mock. You should define it like:

var connectionMock = new Mock<IDbConnection>();

conectionMock
    .Setup(x => x.QueryAsync<It.IsAnyType>(
        It.IsAny<string>(), 
        It.IsAny<object>(), 
        It.IsAny<IDbTransaction>(), 
        It.IsAny<int?>(), 
        It.IsAny<CommandType?>()
    ))
    .ReturnsAsync(new List<SignalsDTO>());

NOTE: it is not clear what types you use and where, so please adjust that, but the idea is here.

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • What do you mean about my types are not clear? I started to code unit test yesterday so I'm pretty new with this stuff. I can see my error is about I have the connectionString as null and thats why it cannot access my data but your code gives me an error on the It.IsAny() because it expect a String – Weenhallo Oct 26 '21 at 12:42
  • @Weenhallo please see update. Also, in ReturnsAsync specify sample object that should be returned by the method. – Michał Turczyn Oct 26 '21 at 12:44
  • Now it gives me another errors(CS0854). It says that an expression tree may not contain a call or invocation that uses optional arguments. My code now is this: conectionMock.Setup(x => x.QueryAsync(It.IsAny())).ReturnsAsync(new List()); – Weenhallo Oct 26 '21 at 13:11
  • @Weenhallo could you share the signature of method `QueryAsync` ? – Michał Turczyn Oct 26 '21 at 13:15
  • Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null); – Weenhallo Oct 26 '21 at 13:27
  • @Weenhallo see update – Michał Turczyn Oct 26 '21 at 13:34
  • I got another exception now. System.NotSupportedException: 'Unsupported expression: x => x.QueryAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) Extension methods (here: SqlMapper.QueryAsync) may not be used in setup / verification expressions.' – Weenhallo Oct 26 '21 at 13:55
  • 1
    @Weenhallo that what i was afraid of. Extension methods cannot be mocked. You need to follow this: https://stackoverflow.com/questions/2295960/mocking-extension-methods-with-moq – Michał Turczyn Oct 26 '21 at 13:58
  • Finally I fixed it without mocks and giving my configuration another database for testing purposes. Thank you for your time and help – Weenhallo Oct 27 '21 at 07:24