I'm using NLog with the ILogger interface (and XUnit.net). I want to verify that the Error() function is called, and I want to make the test as non-fragile as possible. Today, the call within the function under test calls it _log.Error("format string", string, string), but that may change later and I don't want to rewrite the test every time that might get updated. All I actually care about is that the error was logged rather than the specifics of how.
I found another person's question that was similar (Here), but the suggestion there didn't work as I'd hoped (probably because his didn't use overloads).
Today, this works:
var log = Mock.Create<
ILogger
>();
Mock.Arrange(() => log.Error(Arg.IsAny<
string
>(), Arg.IsAny<
string
>(), Arg.IsAny<
string
>())).IgnoreArguments().OccursOnce();
Assert.Throws<
ApplicationException
>(() => myObject.Function(badParameter);
Mock.Assert(log);
What I'd prefer is something like what the other linked article suggested:
var log = Mock.Create<
ILogger
>();
Mock.Arrange(() => log.Error(string.Empty).IgnoreArguments().OccursOnce();
Assert.Throws<
ApplicationException
>(() => myObject.Function(badParameter);
Mock.Assert(log);
I've also tried:
Mock.Arrange(() => log.Error(Arg.IsAny<
string
>(), Arg.IsAny<
object
[]>()).IgnoreArguments().OccursOnce();
The only one that works presently is the match with three string arguments.
I'm assuming this is due to all of the overloads that might match (see below). In this situation, is there any way to accomplish a more generic way of ensuring that the Error function is called without having to make it tied to the argument count?
Here's the most likely matches based on the overloads:
Public method Error(Object)
Public method Error(String,Object[])
Public method Error(String, String)
Public method Error(String, Object, Object)
Here's the full specification.