Moq - Тесты работают нормально, когда выполняются независимо, но не выполняются при выполнении подряд - PullRequest
1 голос
/ 22 февраля 2011

Мы используем Moq для выполнения некоторых модульных тестов, и есть некоторое странное поведение, возможно, это какая-то проблема конфигурации, которую я пропускаю.в основном, у меня есть 2 теста (которые вызывают рабочий процесс Windows, который вызывает пользовательские действия, которые вызывают метод, использующий Invoke. Я не знаю, помогает ли это, но я хочу дать как можно больше информации).Тесты выполняются нормально, когда выполняются в одиночку, но если я выполняю их в одном и том же запуске, первый проходит, а второй не проходит (не имеет значения, если я изменяю их порядок, 2-й всегда не проходит)

Макет воссоздается каждый раз, загружается с использованием Unity.Например:

MockProcessConfigurator = MockFactory.Create<IProcessConfigurator>();
 MockProcessConfigurator.Setup(x => x.MyMethod(It.IsAny<Order>()));
[...]
InversionOfControl.Instance.Register<IProcessConfigurator>(MockProcessConfigurator .Object)

Вызванный вызов (пользовательское действие WF):

var invoker = new WorkflowInvoker(new MyWorkflow());
invoker.Invoke(inputParameter);

. При отладке вызов (Вызов) составляет

MyModuleService.ProcessConfigurator.MyMethod(inputOrder);

.что ProcessConfigurator всегда поддразнивается.

Неудачный вызов в тесте выглядит примерно так:

MockEnvironment.MockProcessConfigurator.Verify(x => x.MyMethod(It.IsAny<Order>()), Times.Exactly(1));

При отладке метод фактически вызывается каждый раз, поэтому я подозреваю, чточто-то беспокоит насчет инстанса.Я немного растерялся, потому что кажется, что все реализовано правильно, но по какой-то причине, когда они запускаются один за другим, возникает проблема

Ответы [ 5 ]

1 голос
/ 27 февраля 2011

Обычное устранение неполадок для этого типа проблемы состоит в том, чтобы попытаться изолировать зависимость между двумя тестами.

  1. Переместить любой установочный код внутрь тестов.
  2. Переместите любой код завершения внутри тестов.
  3. Переместите инициализаторы полей внутрь тестов.(Они запускаются только один раз для каждого прибора!)

Это должно пройти оба теста при совместной работе.Когда у вас появятся зеленые индикаторы, вы можете снова начать перемещать дублирующиеся вещи в инициализаторы / настройки один кусок , выполняя тесты после каждого внесенного вами изменения.

Вы должны бытьв состоянии узнать, что вызывает эту связь между тестами.Удачи!

1 голос
/ 22 февраля 2011

Этот тип ошибки обычно возникает, когда два теста разделяют что-то.

Например, вы создали макет с ожиданием, что метод будет вызываться 1 раз в вашей тестовой настройке, а затем два теста каждый раз вызывают этот метод 1 раз - ваше ожидание не будет выполнено, потому что теперь он был вызван 2 раза .

Это говорит о том, что вы должны перемещать набор ожиданий в каждом тесте.

0 голосов
/ 29 апреля 2015

Думал, я бы добавил дополнительную ситуацию и решение, которое я только что нашел для этой проблемы.

Если у вас есть два отдельных проекта, из которых вы одновременно запускаете тесты, и каждый проект использует свою версию Moq, такая же проблема может возникнуть. Для меня у меня был TestProjectA, использующий Moq 4.2.14, и TestProjectB, использующий Moq 4.2.15 в случае аварии (любезно предоставленный Nuget). При одновременном запуске теста из A и теста из B первый тест завершился успешно, а второй без предупреждения.

Настройка обоих проектов для использования одной и той же версии решила проблему.

0 голосов
/ 27 февраля 2011

Не знаю, насколько это актуально, но MockFactory.Create кажется странным. Я обычно создаю макеты следующим образом:

var mockProcessConfigurator = new Mock<IProcessConfigurator>();

При использовании MockFactory (который мне никогда не нужен), вы обычно создаете его экземпляр. Из moq QuickStart :

var factory = new MockFactory(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock };

Вызов статического метода в MockFactory, кажется, побеждает цель. Если у вас есть нестандартное соглашение об именах, где MockFactory на самом деле является переменной типа MockFactory, это, вероятно, не ваша проблема (но будет постоянным источником путаницы). Если MockFactory является свойством вашего тестового класса, убедитесь, что он воссоздан в SetUp.

Если возможно, я бы исключил фабрику, так как это потенциальный источник общего состояния.

РЕДАКТИРОВАТЬ: Кроме того, WorkflowInvoker.Invoke принимает активность в качестве параметра. Вместо того, чтобы создавать весь рабочий процесс для тестирования настраиваемого действия, вы можете просто передать экземпляр настраиваемого действия. Если это то, что вы хотите протестировать, это сделает ваш модульный тест более сфокусированным.

0 голосов
/ 22 февраля 2011

Чтобы расширить ответ Sohnee , я бы проверил мои методы настройки / демонтажа, чтобы убедиться, что вы все исправляете правильно. У меня были похожие проблемы при массовом запуске тестов, когда я не приводил в порядок мои фиктивные объекты.

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