#c# #unit-testing #mocking #moq #abstract-class
#c# #модульное тестирование #издевательство #moq #абстрактный класс
Вопрос:
В прошлом, когда я хотел смоделировать абстрактный класс, я просто создавал в коде смоделированный класс, который расширял абстрактный класс, а затем использовал этот класс в своем модульном тестировании…
public abstract class MyConverter : IValueConverter
{
public abstract Object Convert(...);
public virtual Object ConvertBack(...) { ... }
}
private sealed class MockedConverter : MyConverter { ... }
[TestMethod]
public void TestMethod1()
{
var mock = new MockedConverter();
var expected = ...;
var actual = mock.ConvertBack(...);
Assert.AreEqual(expected, actual);
}
Я хочу привыкнуть использовать Moq вместо этого. Я не уверен, как бы я использовал Moq для проверки возвращаемого значения по умолчанию моего абстрактного класса. Любой совет здесь?
Комментарии:
1. Издевательство над абстрактными классами во многом похоже на издевательство над интерфейсами. Это довольно прямолинейно.
Ответ №1:
Если вы установите CallBase
значение true, это вызовет реализацию базового класса.
var mock = new Mock<MyConverter> { CallBase = true };
См. Раздел «Настройка макетного поведения» быстрого запуска.
Вызовите реализацию базового класса, если никакое ожидание не переопределяет элемент (он же «Частичные насмешки» в Rhino Mocks): по умолчанию значение false .
Комментарии:
1.И если вы хотите, чтобы это было только для одного члена класса (не для всех членов всего издеваемого класса), вы можете оставить свойство
CallBase
false и вместо этого использовать методCallBase
, например:mock.Setup(x => x.ConvertBack(...)).CallBase();
. Последнее также можно использовать сStrict
mocks.
Ответ №2:
Вы можете настроить макет для абстрактного класса так же, как для интерфейса. Чтобы протестировать абстрактную реализацию, вам нужно настроить макет объекта на вызов базового метода для любых функций, которые не определены:
var mock = new Mock<MyConverter>();
mock.CallBase = true;
Assert.AreEqual(expected value,mock.Object.ConvertBack(...));