NSubstitute ILogger .NET Core [英] NSubstitute ILogger .NET Core
问题描述
我正在尝试围绕异常处理编写单元测试,以便可以验证记录器是否正确记录了异常.我正在使用NSubstitute作为模拟框架,并且必须遵循Microsoft.Extensions.Logging.ILogger
进行测试:
I am trying to write unit tests around my exception handling so that I can verify the my logger is properly logging the exception. I am using NSubstitute as a mocking framework and Microsoft.Extensions.Logging.ILogger
I have to following for my test:
[Fact]
public void LogsExcpetionWhenErrorOccursInCreate()
{
var newUser = new UserDataModel
{
FirstName = "Rick",
MiddleName = "Jason",
LastName = "Grimes",
Email = "rick.grimes@thedead.com",
Created = new DateTime(2007, 8, 15)
};
var exception = new Exception("Test Exception");
// configure InsertOne to throw a generic excpetion
_mongoContext.InsertOne(newUser).Returns(x => { throw exception; });
try
{
_collection.Create(newUser);
}
catch
{
// validate that the logger logs the exception as an error
_logger.Received().LogError(exception.Message);
}
}
通过以下方法测试日志记录:
to test the logging in the following method:
public UserDataModel Create(UserDataModel user)
{
try
{
return MongoContext.InsertOne(user);
}
catch(Exception e)
{
_logger?.LogError(e.Message);
throw new DataAccessException("An error occurred while attempting to create a user.", e);
}
}
我的测试失败,并出现以下错误:
My test fails with the following error:
Message: NSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching:
Log<Object>(Error, 0, Test Exception, <null>, Func<Object, Exception, String>)
Actually received no matching calls.
Received 1 non-matching call (non-matching arguments indicated with '*' characters):
Log<Object>(Error, 0, *Test Exception*, <null>, Func<Object, Exception, String>)
我不确定为什么会失败,因为即使在错误消息中,调用也一样.
I'm not sure why this is failing because even in then error message the calls are the same.
提前谢谢!
更新:
这里是测试的构造函数,这是我在其中插入记录器模拟程序的地方:
Here is the constructor for the test, this is where I am injecting the logger mock:
public UserCollectionTest()
{
_mongoContext = Substitute.For<IMongoContext<UserDataModel>>();
_logger = Substitute.For<ILogger>();
// create UserCollection with our mock client
_collection = new UserCollection(_mongoContext, _logger);
}
推荐答案
LogError不是ILogger方法,因此当您尝试检查是否已使用某些参数调用此方法时,NSubstitute会尝试以某种方式处理它(我不知道如何完全)并失败.
LogError is not a ILogger method, so when you try to check that this method was called with certain parameters NSubstitute tries to handle it somehow(I do not know how exactly) and fails.
LogError扩展方法的代码为:
The code of LogError extension method is:
public static void LogError(this ILogger logger, string message, params object[] args)
{
if (logger == null)
throw new ArgumentNullException("logger");
logger.Log<object>(LogLevel.Error, (EventId) 0, (object) new FormattedLogValues(message, args), (Exception) null, LoggerExtensions._messageFormatter);
}
因此,您必须检查是否调用了Log方法.
So you have to check that Log method was called.
我简化了您的示例.我认为主意应该很清楚.
I simplified your example a bit. I think idea should be clear.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var logger = Substitute.For<ILogger>();
try
{
Create(logger);
}
catch
{
logger.CheckErrorMessage("My Message");
}
}
public string Create(ILogger logger)
{
try
{
throw new Exception("My Message");
}
catch (Exception e)
{
logger?.LogError(e.Message);
throw new Exception("An error occurred while attempting to create a user.", e);
}
}
}
public static class TestExtensions
{
public static void CheckErrorMessage(this ILogger logger, string message)
{
logger.Received().Log(
LogLevel.Error,
Arg.Any<EventId>(),
Arg.Is<object>(o => o.ToString() == message),
null,
Arg.Any<Func<object, Exception, string>>());
}
}
这篇关于NSubstitute ILogger .NET Core的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!