Moq SetupGet错误但在.Object上设置属性工作正常

时间:2010-09-23 07:20:44

标签: unit-testing installation moq

我正在尝试为模拟(模型)定义返回值。

任何人都可以向我解释为什么以下代码因“不可覆盖的成员上的无效设置”而失败:

model.SetupGet(x => x.PostCodeSearch).Returns(It.IsAny<string>);

然而我能做到这一点并且工作正常:

model.Object.PostCodeSearch = "Any value as long as it's not null or empty";

错误消息足够清楚但似乎很奇怪我可以直接在Object属性上将值应用于属性。如果我可以做后者,那么SetUpGet有什么意义呢?

1 个答案:

答案 0 :(得分:1)

确保在伪造类型上声明PostCodeSearch virtual

public virtual string PostCodeSearch { get; set; }

moq 只能伪造可覆盖的属性。

编辑:处理非可覆盖的

如果伪造的类型无法更改,则有不同的选择:

更改生产代码以使用伪造类的包装。包装器将具有与包装类相同的API,它所做的就是将调用路由到包装对象。包装器将方法和属性声明为virtual。这样,您在代码中获得的行为几乎没有变化。

例如,如果伪造的原始类是MyClass:

public class MyClassWrapper
{
    MyClass myClass;

    MyClassWrapper(MyClass myClass)
    {
        this.myClass = myClass;
    }

    public virtual string PostCodeSearch
    {
        get { return myClass.PostCodeSearch; }
        set { myClass.PostCodeSearch = value; };
    }
}

生产代码将使用MyClassWrapper代替MyClass,并且使用这一点变化可以使代码可测试。

另一种选择是使用隔离框架。隔离框架可以伪造不可覆盖的成员,静态成员,密封类......

例如,使用Typemock Isolator

MyClass myClass = new MyClass();
Isolate.WhenCalled(() => myClass.PostCodeSearch).WillReturn("faked value");

在此示例中,伪造行为直接在原始类上设置。这里的优点是生产代码中不需要进行任何更改以使其可测试。

免责声明 - 我在Typemock工作