代码之家  ›  专栏  ›  技术社区  ›  Darren Lewis

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

  •  2
  • Darren Lewis  · 技术社区  · 14 年前

    我试图为Mock(model)定义一个返回值。

    有人能解释一下为什么下面的代码在“非重写成员上的设置无效”时失败:

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

    但我能做到这一点,而且效果很好:

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

    1 回复  |  直到 14 年前
        1
  •  1
  •   Elisha    14 年前

    确保 PostCodeSearch 已声明 virtual 关于伪造的类型。

    public virtual string PostCodeSearch { get; set; }
    

    最小起订量 只能伪造可重写的属性。

    编辑:

    如果无法更改伪造的类型,则有不同的替代方法:

    将生产代码更改为使用伪造类的包装器。包装器将具有与包装类相同的API,它所做的只是将调用路由到包装对象。包装器将方法和属性声明为 事实上的

    例如,如果伪造的原始类是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");
    

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