I have the following code,
namespace MarketData.Service.Diagnostics
{
using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.Extensions.Logging;
public class MarketsDataUploader
{
private readonly ILogger<MarketDataService> logger;
private readonly Func<IDbConnection> connectionFactory;
public MarketsDataUploader(ILogger<MarketDataService> logger, Func<IDbConnection> connectionFactory)
{
this.logger = logger;
this.connectionFactory = connectionFactory;
}
public void WriteData(IEnumerable<MarketData> marketData)
{
try
{
using var connection = this.connectionFactory.Invoke();
connection.Open();
foreach (var item in marketData)
{
using var command = connection.CreateCommand();
command.CommandText =
"INSERT INTO MarketData (SchemeId, AnalysisDate, CreatedDate, Duration, [Value], Status) " +
"VALUES (@SchemeId, @AnalysisDate, @CreatedDate, @Duration, @Value, @Status)";
command.Parameters.Add(CreateParameter(command, "@SchemeId", item.SchemeId));
command.Parameters.Add(CreateParameter(command, "@AnalysisDate", item.AnalysisDate));
command.Parameters.Add(CreateParameter(command, "@CreatedDate", item.CreatedDate));
command.Parameters.Add(CreateParameter(command, "@Duration", item.Duration));
command.Parameters.Add(CreateParameter(command, "@Value", item.Value));
command.Parameters.Add(CreateParameter(command, "@Status", modelRunStatistic.Status));
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
this.logger.LogError(ex, ex.Message);
}
}
private static IDbDataParameter CreateParameter(IDbCommand command, string parameterName, object value)
{
var parameter = command.CreateParameter();
parameter.ParameterName = parameterName;
parameter.Value = value;
return parameter;
}
}
}
and the test
[Fact]
public void WriteData_DatabaseThrowsException_LogsError()
{
// Arrange
var marketsDataUploader = new MarketsDataUploader(mockLogger.Object, connectionFactory);
var marketsData = new List<MarketData>
{
new ModelRunStatistic
{
SchemeId = Guid.NewGuid(),
AnalysisDate = DateTime.UtcNow,
CreatedDate = DateTime.UtcNow,
Duration = TimeSpan.FromSeconds(5),
Value = 100000,
Status = 1
}
};
mockConnection.Setup(conn => conn.Open()).Throws(new InvalidOperationException("Test exception"));
// Act
marketsDataUploader.WriteData(marketsData);
// Assert
mockLogger.Verify(logger => logger.LogError(It.IsAny<InvalidOperationException>(), "Test exception"), Times.Once);
}
but when it gets to mockLogger.Verify(logger => logger.LogError(It.IsAny<InvalidOperationException>(), "Test exception"), Times.Once);
it returns the following error
System.NotSupportedException: 'Unsupported expression: logger => logger.LogError(It.IsAny(), "Test exception", new[] { }) Extension methods (here: LoggerExtensions.LogError) may not be used in setup / verification expressions.'
Any ideas what I do wrong?
You can't assert directly against LogError
because it is an extension method.
You can verify the logger calls like this:
LogLevel expectedLevel = LogLevel.Error;
Times expectedOccasions = Times.Once;
loggerMock.Verify(l => l.Log(expectedLevel , It.IsAny<EventId>(),
It.IsAny<It.IsAnyType>(), It.IsAny<InvalidOperationException>(),
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()),
expectedOccasions);