使用RhinoMock或Moq测试方法的内部

时间:2009-12-17 11:12:29

标签: javascript unit-testing mocking rhino-mocks moq

对于这个嘲弄的事情来说,我有几个问题。

如果我错了,请纠正我: Mocking没有初始化真正的方法,即Mocking实际上不会调用你的类的构造函数。相反,它会像查看类的签名并创建具有该签名但没有任何方法功能的对象。如果你只需要那种类型的对象但又不想测试它的内部结构,这很有用。如果您实际测试的对象依赖于它。

我正在尝试测试方法的内部,这是否意味着我必须创建该方法所属的类的实例?

1 个答案:

答案 0 :(得分:7)

摘要:动态模拟不会帮助您测试类型的内部,但您不应该首先尝试这样做。


你的描述基本上是正确的,但它有点复杂。基本上,动态模拟不会做任何你不能手工做的事情

假设您正在编写针对此类接口的编程:

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";
    }
}

动态模拟库也可以这样做,抽象方法也是如此。在这种情况下,将调用基类的构造函数 ,因为这就是.NET的工作原理。

但是,您无法编写覆盖非虚拟或内部成员的代码,也无法编写动态模拟代码。他们只能做你手边的事情。

一条建议:仅通过公共API测试内部成员

警告:上面的描述适用于大多数动态模拟,但TypeMock除外,它是不同的......可怕的。