【发布时间】:2010-12-30 16:17:26
【问题描述】:
或者这个类也可以实现一个抽象类?
【问题讨论】:
-
几天前你刚刚问了同样的问题:stackoverflow.com/questions/1969497/…
标签: moq
或者这个类也可以实现一个抽象类?
【问题讨论】:
标签: moq
要模拟一个类型,它必须要么是一个接口(这也被称为是纯虚拟)或具有虚拟成员(抽象成员也是虚拟的)。
根据这个定义,你可以模拟所有虚拟的。
从本质上讲,动态模拟不会做任何手工无法做到的事情。
假设您正在针对这样的接口进行编程:
public interface IMyInterface
{
string Foo(string s);
}
您可以手动创建 IMyInterface 的特定于测试的实现,该实现忽略输入参数并始终返回相同的输出:
public class MyClass : IMyInterface
{
public string Foo(string s)
{
return "Bar";
}
}
但是,如果您想测试消费者如何响应不同的返回值,这会变得非常重复,因此您可以让框架动态创建它们,而不是手动编写 Test Doubles给你。
想象一下,动态模拟确实编写了类似于上面的 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 除外,它是不同的并且......可怕。
【讨论】:
您可以使用 Moq 从接口和现有类创建模拟。对类有一些要求。类不能被密封。此外,被模拟的方法必须标记为虚拟的。您不能模拟静态方法(使用适配器模式模拟静态方法)。
【讨论】: