#c# #unit-testing #moq #hangfire
#c# #модульное тестирование #moq #hangfire
Вопрос:
Я использую Hangfire для планирования некоторых заданий. У всех моих заданий есть дата расписания, поэтому я использую метод статического расширения расписания
public static string Schedule([NotNull] this IBackgroundJobClient client, [InstantHandle][NotNull] Expression<Action> methodCall, DateTimeOffset enqueueAt);
Я хочу провести модульное тестирование своих методов, чтобы я мог проверить, действительно ли запускается Hangfire.
Для этого я следовал документации Hangfire по модульному тестированию (https://docs .hangfire.io/en/latest/background-methods/writing-unit-tests.html ), который предлагает издеваться IBackgroundJobClient
и проверять единственный общедоступный метод создания, который у него есть:
string Create([NotNull] Job job, [NotNull] IState state);
Но я вижу, что для вызовов расписания это не вызывается, вместо этого вызывается другая перегрузка, которая не является общедоступной, поэтому я получаю следующую ошибку:
Message: Moq.MockException :
Expected invocation on the mock at least once, but was never performed: x => x.Create(It.IsAny<job>(), It.IsAny<enqueuedstate>())
No setups configured.
Performed invocations:
IBackgroundJobClient.Create(JobService.TaskFunction, ScheduledState)
Тем не менее, я предпринял попытку с Enqueue
помощью метода, и, похоже, это работает с макетом. Но мне нужно использовать Schedule
.
Другим вариантом было бы подтвердить перегрузку, которую он фактически вызывает
public static string Create([NotNull] this IBackgroundJobClient client, [InstantHandle][NotNull] Expression<Action> methodCall, [NotNull] IState state);
Но поскольку это метод расширения, это недопустимый подход для Moq.
Message: System.NotSupportedException : Invalid verify on an extension method: x => x.Create(It.IsAny<Expression<Action>>(), It.IsAny<EnqueuedState>())
Итак, как я могу модульно протестировать Hangfire для Schedule
метода?
Ответ №1:
В примере, на который вы ссылаетесь, используется другой метод расширения, который в конце вызывает другой IBackgroundJobClient
метод, github. Был вызван следующий метод:
client.Create(Expression<Action> methodCall, new EnqueuedState());
Это идеально подходит Verify
для примера.
С другой стороны, вы вызываете Schedule
метод github . Schedule
метод в конце вызывает следующее:
client.Create(Expression<Action> methodCall, new ScheduledState(enqueueAt.UtcDateTime))
Который также является методом выражения, поэтому вам нужно углубиться еще на один уровень, где interface
был вызван фактический метод:
string Create([NotNull] Job job, [NotNull] IState state);
Как вы можете видеть из самой ошибки, ваши ожидания не совпадают с фактическим вызовом:
Performed invocations:
IBackgroundJobClient.Create(JobService.TaskFunction, ScheduledState)
Ваше утверждение должно быть примерно таким:
// Assert
client.Verify(x => x.Create(
It.IsAny<Job>(), //you could as in example check actual method name
It.IsAny<IState>()); //you could check actual offset
Комментарии:
1. Это невозможно утверждать … поскольку эта перегрузка Create является методом расширения. Я уже пробовал это. Я обновлю свой пост
2. @keycad вы правы, тогда всего на один уровень глубже :), я обновил
3. Итак, проблема была в моем
IsAny<EnqueuedState>
, я не использовал правильный интерфейс, спасибо 🙂