Moq проверяет подпись метода, видит вызовы, но не совпадает на них? - PullRequest
0 голосов
/ 11 января 2019

У меня есть такой интерфейс:

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>, но это было также бесполезно.

Может кто-нибудь объяснить это поведение? Что мне нужно сделать, чтобы исправить мой тест?

1 Ответ

0 голосов
/ 11 января 2019

Эта строка всегда будет неуспешной:

_statisticsCollector.Verify(
    x => x.Measure(It.IsAny<string>(), It.IsAny<long>(), It.IsAny<IDictionary<string, string>>()), Times.Exactly(5));

Это происходит потому, что вы говорите макету, что он должен получить long во втором аргументе, НО интерфейс говорит, что во втором аргументе он получит десятичное число:

public interface IStatisticsCollector : IDisposable
{
    Task Measure(string metricName, decimal value, IDictionary<string, string> tags = null);
}

Поскольку десятичная дробь не может быть длинной, ваш verificatin всегда потерпит неудачу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...