Вы можете использовать виртуальные методы, но их лучше , если вы используете интерфейс.
Причина, по которой я говорю, заключается в следующем:
var mockObject = new Mock<IMyObject>();
Если вы используете виртуальный метод, он становится:
var mockObject = new Mock<MyObject>(params...);
Вы вынуждены включить параметры для конкретных объектов, но вам явно не нужно для интерфейсов. Все тесты, использующие конкретные классы, потребуют обновления, если вы решите изменить конструктор класса позднее. Я был сожжен этим в прошлом, поэтому старайтесь больше не использовать виртуальные методы для тестирования.
Я должен добавить, что, пытаясь издеваться над конкретными типами, вы побеждаете цель насмешливых структур. Вы должны быть насмешливыми ролями, а не типами . Поэтому, работая с абстракцией, в этом случае интерфейс - это отличная вещь.
Другая причина заключается в том, как интерфейсы работают, интерфейсы определяют контракт, но не поведение. Они должны использоваться, когда у вас есть несколько реализаций, и я тестирую класс как поведение, следовательно, является веской причиной для введения нового интерфейса.