Действительно ли возможно использовать Moq для насмешки объекта, который реализует интерфейсный и абстрактный класс?
Т.е.:
public class MyClass: SomeAbstractClass, IMyClass
Можно ли дразнить это?
Вы можете насмехаться над любым интерфейсом, а также над любыми абстрактными или виртуальными членами. В принципе, это все.
Это означает, что абсолютно возможно следующее:
var imock = new Mock<IMyClass>();
var aMock = new Mock<SomeAbstractClass>();
Если члены, унаследованные от SomeAbstractClass, не опечатаны, вы также можете насмехаться над MyClass:
var mcMock = new Mock<MyClass>();
Имеет ли это смысл или нет, зависит от реализации MyClass. Допустим, SomeAbstractClass определено так:
public abstract class SomeAbstractClass
{
public abstract string GetStuff();
}
Если метод GetStuff в MyClass реализован таким образом, вы все равно можете его переопределить:
public override string GetStuff()
{
return "Foo";
}
Это позволит вам написать:
mcMock.Setup(x => x.GetStuff()).Returns("Bar");
так как если он явно не запечатан, то GetStuff все равно виртуальен. Однако, если бы вы написали GetStuff так:
public override sealed string GetStuff()
{
return "Baz";
}
вы не смогли бы насмехаться над ним. В таком случае, вы бы получили исключение из Moq, утверждающее, что это недействительное переопределение невиртуального члена (так как теперь он запечатан
).
Ваш вопрос не имеет смысла. Moq можно использовать для издевательств над абстрактными классами и интерфейсами. Так как MyClass
ни то, ни другое, вы не можете создать из него насмешку.
Однако я не думаю, что это проблема, так как потребители вашего экземпляра MyClass скорее всего будут ожидать экземпляр SomeAbstractClass
или IMyClass
, а не экземпляр MyClass
. Если они действительно ожидают экземпляр MyClass
, то вам нужно сделать некоторую абстракцию поверх него. Этого можно добиться либо с помощью интерфейса SomeAbstractClass
, реализующего интерфейс IMyClass
, либо с помощью интерфейса IMyClass
, раскрывающего методы и свойства SomeAbstractClass
.