Почему мои модульные тесты с использованием Moq's Verify () недетерминированы? - PullRequest
0 голосов
/ 01 мая 2018

Мы используем Moq 4 для наших модульных тестов, в частности, тестов модулей контроллера. Мы используем метод Moq Verify (), чтобы убедиться, что ошибка была зарегистрирована. Проблема в том, что тесты могут быть пройдены, но затем не пройдут при следующем запуске.

Мы используем Serilog для нашего регистратора.

Метод действия выглядит как

public IActionResult Index(){
    try{
         var data = _repository.GetData();
         return View(data);
    }catch(Exception e){
        Log.Error(e.Message);
    }
}

Итак, модульный тест использует

_mockLogger.Verify(x=> x.Write(LogEventLevel.Error,It.IsAny<string>()));

mockLogger настраивается в конструкторе теста как

var _mockLogger = new Mock<Serilog.ILogger>();
Log.Logger = _mockLogger.Object;
//...

и репозиторий высмеивается, чтобы вызвать исключение при вызове.

При сбое мы получаем сообщение об ошибке

"Moq.MoqException ожидал вызова на Mock хотя бы один раз, но никогда не выполнялся x=>x.Write(LogEventLevel.Error,It.IsAny<string>())"

Есть идеи?

1 Ответ

0 голосов
/ 05 мая 2018

Невозможно увидеть, в чем проблема, по опубликованному коду. И я ценю, как тяжело сделать MCVE для этого. Итак, я собираюсь сделать две догадки.

Угадай 1: Я подозреваю, что причиной твоей проблемы является использование static s в твоем коде, особенно для логгера.

Я подозреваю, что происходит то, что другие тесты (не показанные в посте) также изменяют / определяют, как должен вести себя регистратор, и, поскольку регистратор статичен, тесты мешают друг другу.

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

Угадай 2: На основании части поста, в которой говорится "... настройка в конструкторе теста", вы не сказали (или не отметили), какую среду тестирования вы используете; но те немногие, которые я использовал, предпочитают, чтобы вы делали подобные вещи в атрибутивных методах, а не в конструкторе теста. Например, NUnit имеет OneTimeSetUp (до запуска любого из тестов в этом классе), SetUp (до запуска каждого теста в этом классе), TearDown (после запуска каждого теста в этом классе), OneTimeTearDown (после всех тестов в этом классе работают). Возможно, что конструкторы ваших тестов вызываются в том порядке, который вы не ожидаете и который не поддерживается вашей средой тестирования; тогда как приписанная последовательность методов гарантируется каркасом.

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