Подтвердить что ты не робот

Как использовать 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 для проверки возвращаемого значения по умолчанию моего абстрактного класса. Любой совет здесь?

4b9b3361

Ответ 1

Если вы установите для параметра CallBase значение true, оно вызовет реализацию базового класса.

var mock = new Mock<MyConverter> { CallBase = true };

См. Настройка макетного поведения "Настройка макета" в разделе "Быстрый старт".

Вызвать реализацию базового класса, если никакое ожидание не отменяет член (a.k.a. "Частичные Mocks" в Rhino Mocks): по умолчанию false.

Ответ 2

Вы можете настроить Mock на абстрактный класс, как на интерфейсе. Чтобы протестировать абстрактную реализацию, вам нужно установить mock-объект для вызова базового метода для любых не определенных функций:

var mock = new Mock<MyConverter>();
mock.CallBase = true;
Assert.AreEqual(expected value,mock.Object.ConvertBack(...));

Ответ 3

Прочитали ли вы какие-нибудь из руководств по началу работы для Moq? Это довольно просто:

var mock = new Mock<MyConverter>();
var expected = ...;
mock.Setup(m => m.ConvertBack(...)).Returns(expected);
var actual = m.Object.ConvertBack(...);
Assert.AreEqual(expected, actual);

Но, конечно, это плохой пример, потому что вы на самом деле не позволяете ему тестировать какие-либо реальные классы. Mocking полезен для предоставления макета реальному классу, который вы хотите unit test, и который, как вы ожидаете, вызовет метод, который вы издевались.

Update

После повторного чтения вашего вопроса (с заголовком, обновленным Энтони Пегемом), мне интересно, пытаетесь ли вы протестировать реальную реализацию ConvertBack, насмехаясь над реализацией Convert. Если это так, у меня есть несколько наблюдений:

  • ConvertBack, вероятно, не будет объявлен virtual, по крайней мере, для этого примера,
  • Возможно, вы захотите реорганизовать свой код, чтобы Convert и ConvertBack были частью различных сервисов: я ощущаю запах кода, возможно, возникающий из-за отсутствия разделения проблем.

Если вы уверены, что вам нужно это сделать, оно должно быть относительно простым:

var mock = new Mock<MyConverter>() {CallBase = true}; // hat tip: adrift
mock.Setup(m => m.Convert(...)).Returns(...);
var expected = ...;
var actual = m.Object.ConvertBack(...);
Assert.AreEqual(expected, actual);