我正在尝试围绕我的异常处理编写单元测试,以便我可以验证我的日志记录器是否正确记录异常。我使用NSubstitute作为模拟框架,并且我必须遵循Microsoft.Extensions.Logging.ILogger
进行测试:
[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);
}
}
要测试日志记录,请使用以下方法:
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);
}
}
我的测试失败,出现以下错误:
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>)
我不知道为什么会失败,因为即使在错误消息中,调用也是相同的。
先谢谢你了!
更新:
下面是测试的构造函数,这是我注入logger mock的地方:
public UserCollectionTest()
{
_mongoContext = Substitute.For<IMongoContext<UserDataModel>>();
_logger = Substitute.For<ILogger>();
// create UserCollection with our mock client
_collection = new UserCollection(_mongoContext, _logger);
}
4条答案
按热度按时间i1icjdpr1#
LogError不是一个ILogger方法,所以当你试图检查这个方法是用某些参数调用的时候,NSubstitute会试图以某种方式处理它(我不知 prop 体是怎么做的),但失败了。
LogError扩展方法的代码为:
因此,您必须检查Log方法是否被调用。
我把你的例子简化了一点,我想思路应该很清晰。
rryofs0p2#
看起来接受的答案在.NET Core 3或.NET 5中不起作用。
以下是在github issue中找到的解决方法
创建新的MockLogger类
用新的模拟记录器替换模拟记录器
使用新的记录器检查调用
要使用泛型
ILogger<T>
,只需将类更改为pdsfdshx3#
这是我的方法,它走得更远。扩展Githhub问题。
第一个记录器:
现在使用:
它允许单独测试日志参数。
zlhcx6iw4#
使用下面的名称空间
使用NSubstitute.ExceptionExtensions;
并更新代码以引发异常而不是返回异常。
_mongoContext.InsertOne(newUser).Throw(exception);