或者该类是否也可以实现抽象类?
答案 0 :(得分:16)
要模拟某个类型,它必须是一个接口(这也称为纯虚拟)或具有虚拟成员(抽象成员也是虚拟的)。
通过这个定义,您可以模拟 virtual 的所有内容。
基本上,动态模拟不会做任何你不能手工做的事情。
假设您正在编写针对此类接口的编程:
public interface IMyInterface
{
string Foo(string s);
}
您可以手动创建IMyInterface的特定于测试的实现,忽略输入参数并始终返回相同的输出:
public class MyClass : IMyInterface
{
public string Foo(string s)
{
return "Bar";
}
}
但是,如果您想测试消费者如何响应不同的返回值,那么这会变得非常重复,因此您可以让框架动态创建它们,而不是编写测试双打。对你而言。
想象一下,动态模拟真的编写类似于上面的MyClass实现的代码(它们实际上并没有编写代码,它们动态地发出类型,但它足够准确)。
以下是如何使用Moq定义与MyClass相同的行为:
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派生并覆盖Ploeh方法,因为它是虚拟的:
public class TestSpecificChild : MyBase
{
public override string Ploeh()
{
return "Ndøh";
}
}
动态模拟库也可以这样做,抽象方法也是如此。
但是,您无法编写覆盖非虚拟或内部成员的代码,也无法编写动态模拟代码。他们只能做你手边的事情。
警告:上面的描述适用于大多数动态模拟,但TypeMock除外,它是不同的......可怕的。
答案 1 :(得分:3)
您可以使用Moq从接口和现有类创建模拟。这些课程有一些要求。班级无法封存。此外,被模拟的方法必须标记为虚拟。您不能模拟静态方法(使用适配器模式来模拟静态方法)。