Для насмешки объекта это должно или реализовывать интерфейс или отмеченное виртуальный?

или класс может реализовывать абстрактный класс также?

6
задан Mark Seemann 27 February 2013 в 15:29
поделиться

2 ответа

Чтобы высмеять тип, он должен либо быть интерфейсом (это также называется чисто виртуальным), либо иметь виртуальные члены (абстрактные члены также виртуальны).

По этому определению, вы можете высмеивать все, что является виртуальным.

По сути, динамические высмеивания не делают ничего, что вы не могли бы сделать вручную.

Допустим, вы программируете на основе такого интерфейса, как этот:

public interface IMyInterface
{
    string Foo(string s);
}

Можно вручную создать тестовую реализацию IMyInterface, которая игнорирует входной параметр и всегда возвращает один и тот же вывод:

public class MyClass : IMyInterface
{
    public string Foo(string s)
    {
        return "Bar";
    }
}

Однако, это становится очень быстро повторяющимся, если вы хотите проверить, как потребитель реагирует на различные возвращаемые значения, поэтому вместо того, чтобы вручную кодировать ваши Test Doubles, вы можете иметь фреймворк, который динамически создаёт их для вас.

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

Вот как можно определить то же самое поведение, что и MyClass с Moq:

var mock = new Mock<IMyInterface>();
mock.Setup(x => x.Foo(It.IsAny<string>())).Returns("Bar");

В обоих случаях, при создании объекта будет вызван конструктор созданного класса. Так как интерфейс не имеет конструктора, то это будет конструктор по умолчанию (MyClass и динамически испускаемый класс соответственно).

То же самое можно сделать и с конкретными типами, такими как этот:

public class MyBase
{
    public virtual string Ploeh()
    {
        return "Fnaah";
    }
}

вручную, вы сможете извлечь из MyBase и переопределить метод Плоэ, так как он виртуальный:

public class TestSpecificChild : MyBase
{
    public override string Ploeh()
    {
        return "Ndøh";
    }
}

Библиотека динамического mock может сделать то же самое, и то же самое верно и для абстрактных методов.

Однако, вы не можете написать код, который переопределяет невиртуальный или внутренний член, и динамический mock также не может быть динамическим. Они могут делать только то, что можно сделать вручную.

Caveat: Вышеприведенное описание верно для большинства динамических насмешек, за исключением TypeMock, который отличается и ... пугает.

.
16
ответ дан 8 December 2019 в 12:20
поделиться

Из блога Стивена Уолтера:

Вы можете использовать Moq для создания макетов как из интерфейсов, так и из существующих классов. К классам предъявляются некоторые требования. Класс не может быть загерметизирован. Более того, высмеиваемый метод должен быть помечен как виртуальный. Нельзя насмехаться над статическими методами (используйте шаблон адаптера для насмешки статического метода).

3
ответ дан 8 December 2019 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: