Модульное тестирование IBackgroundJobClient.Расписание

#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> , я не использовал правильный интерфейс, спасибо 🙂