У меня есть такой интерфейс:
public interface IStatisticsCollector : IDisposable
{
Task Measure(string metricName, decimal value, IDictionary<string, string> tags = null);
}
Я ввожу это IStatisticsCollector
в свой класс и использую его так:
var stopwatch = new Stopwatch();
await dataCollector.Measure("rbk_init", stopwatch.ElapsedMilliseconds);
...
await dataCollector.Measure("rbk_compiled", stopwatch.ElapsedMilliseconds);
...
Настройка моего модульного теста, чтобы убедиться, что я записываю все статистические данные, которые я хочу, я высмеиваю IStatisticsCollector
:
private readonly Mock<IStatisticsCollector> _statisticsCollector = new Mock<IStatisticsCollector>();
_statisticsCollector.Setup(x => x.Measure(It.IsAny<string>(), It.IsAny<long>(), It.IsAny<IDictionary<string, string>>())).Verifiable();
Когда я запускаю свой модульный тест, моя проверка не проходит в этой строке:
//assert
_statisticsCollector.Verify(
x => x.Measure(It.IsAny<string>(), It.IsAny<long>(), It.IsAny<IDictionary<string, string>>()), Times.Exactly(5));
... со следующим сообщением:
Moq.MockException :
Expected invocation on the mock exactly 5 times, but was 0 times: x => x.Measure(It.IsAny<string>(), (decimal)It.IsAny<long>(), It.IsAny<IDictionary<string, string>>())
Configured setups:
IStatisticsCollector x => x.Measure(It.IsAny<string>(), (decimal)It.IsAny<long>(), It.IsAny<IDictionary<string, string>>())
Performed invocations:
IStatisticsCollector.Measure("rbk_init", 31, null)
IStatisticsCollector.Measure("rbk_compiled", 35, null)
IStatisticsCollector.Measure("rbk_stored", 36, null)
IStatisticsCollector.Measure("rbk_db_updated", 352, null)
IStatisticsCollector.Measure("rbk_completed", 361, null)
at Moq.Mock.VerifyCalls(Mock targetMock, InvocationShape expectation, LambdaExpression expression, Times times, String failMessage) in C:\projects\moq4\src\Moq\Mock.cs:line 378
... это было странно, потому что, похоже, он захватил 5 совпадающих вызовов, но, по-видимому, ни один из них на самом деле не совпадал. Теперь я предположил, что это может быть связано с тем, что ElapsedMilliseconds
секундомера был длинным, но интерфейс ожидал десятичное число (с неявным приведением), поэтому я изменил проверку для поиска It.IsAny<decimal>()
, но это дало мне неожиданный результат:
Moq.MockException :
Expected invocation on the mock exactly 5 times, but was 1 times: x => x.Measure(It.IsAny<string>(), It.IsAny<decimal>(), It.IsAny<IDictionary<string, string>>())
Configured setups:
IStatisticsCollector x => x.Measure(It.IsAny<string>(), It.IsAny<decimal>(), It.IsAny<IDictionary<string, string>>())
Performed invocations:
IStatisticsCollector.Measure("rbk_init", 28, null)
at Moq.Mock.VerifyCalls(Mock targetMock, InvocationShape expectation, LambdaExpression expression, Times times, String failMessage) in C:\projects\moq4\src\Moq\Mock.cs:line 378
Он нашел один ... и только один. Кажется, не было выброшено исключение, поэтому я не знаю, почему будет только одно.
Я также отметил нулевое значение в необязательном аргументе и попытался проверить на нулевое значение вместо IDictionary<string, string>
, но это было также бесполезно.
Может кто-нибудь объяснить это поведение? Что мне нужно сделать, чтобы исправить мой тест?