Почему для издевательства над репозиторием требуется виртуальная функция, а издевательство над IRepository переопределяет существующую функцию?

#c# #asp.net-core #nunit #moq #irepository

#c# #asp.net-core #nunit #moq #irepository

Вопрос:

Я провожу модульное тестирование с использованием NUnit и фреймворка Moq. Когда я пытаюсь издеваться над IRepository с помощью mockRepo.Setup(x=>x.GetStr(It.IsAny)()).Возвращает(str) затем метод, который должен быть протестирован, переопределяется внутри класса репозитория, и сборка завершается с ошибкой. Но вместо того, чтобы издеваться над IRepository, если я издеваюсь над репозиторием, делая метод, который должен быть протестирован как виртуальный, тогда данные подвергаются издевательству и тест выполняется.

Комментарии:

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

2. Почему вы издеваетесь над тестируемым методом? Вы должны издеваться над зависимостями , а не над тестируемой системой .

3. @HimBromBeere большое вам спасибо, я сейчас пробую это таким образом и в значительной степени преуспеваю.

Ответ №1:

Любой вид издевательства зависит от переопределяемых членов. Ваш mocking-framework создаст некоторый класс, который либо реализует ваш интерфейс, либо переопределяет ваш класс. Итак, то, что создает фреймворк, похоже на следующее:

 class WeirdClassName : IRepository
{
    string GetString(object o) => "SomeString";
}
  

или, если ваш член будет членом класса, это:

 class WeirdClassName : Repository
{
    string override GetString(object o) => "SomeString";
}
  

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

В вашем случае, похоже, есть некоторая разница в тесте в зависимости от того, издеваетесь ли вы над интерфейсом или классом. Это, вероятно, указывает на то, что ваш тест зависит от некоторых внутренних компонентов класса — например, некоторой инициализации в репозитории. Вы должны либо издеваться над этим, либо отделить свой тест от этой зависимости.

Комментарии:

1. Спасибо @HimBromBeere за решение. Сейчас я ищу издевательство над зависимостью. И это работает.