代码之家  ›  专栏  ›  技术社区  ›  Sam Holder Brian Adams

为什么我的部分模拟会模拟所有虚拟方法,即使没有设定期望值?

  •  2
  • Sam Holder Brian Adams  · 技术社区  · 16 年前

    我有一个用户控件,它在我要测试的validateChildren方法中进行一些验证。我已经创建了用户控件的部分模拟,但是尽管我没有对validateChildren方法设置任何期望,但我只是调用它,它只是被跳过,方法中的代码永远不会执行。为了尝试和理解正在发生的事情,我创建了一个简单的测试,如下所示:

    public class Foo
    {        
        public virtual bool Method1()
        {
            throw new NotImplementedException();
        }
    
        public virtual bool Method2()
        {
            return Method1();
        }
    }
    

    用这个来测试它:

    [Test]
    public void TestFooMethods ()
    {
        MockRepository m = new MockRepository();
        Foo foo = m.PartialMock<Foo>();
    
        RhinoMocksExtensions.Expect<Foo,bool>(
                                 foo, 
                                 delegate (Foo obj)
                                 {
                                     return obj.Method1();
                                 }
                             ).Return(true);
    
        Assert.IsTrue (foo.Method2());
    }
    

    现在我希望foo.method1可以被模仿,而foo.method2不能被模仿。但这总是返回false,如果我尝试在调试器foo.method2()中单步执行,那么我就无法单步执行。

    有什么想法吗?

    2 回复  |  直到 11 年前
        1
  •  5
  •   Jon Cahill    16 年前

    如果模拟一个对象,它将覆盖所有抽象/虚拟方法,而不管模拟的类型如何。但是,您可以做的是对您的方法进行期望,并告诉它执行它所覆盖的原始方法,方法是使用:

    CallOriginalMethod(OriginalCallOptions.CreateExpectation);
    

    你没有使用犀牛嘲笑它的设计方式,这也可能导致你的麻烦。我已经按照使用C 3.0和lambda和扩展方法编写测试的方式重新编写了测试:

    [TestMethod]
    public void TestFooMethods()
    {
        //Generate a new Mock to test against
        Foo foo = MockRepository.GenerateMock<Foo>();
    
        //Expect a call to Method1 on object foo and return true
        foo.Expect(f => f.Method1()).Return(true);
        //Expect a call to Method2 on object foo and call the original method
        foo.Expect(f => f.Method2()).CallOriginalMethod(OriginalCallOptions.CreateExpectation);
    
        Assert.IsTrue(foo.Method2());
    
        //Verify all our expectations on foo
        foo.VerifyAllExpectations();
    }
    
        2
  •  0
  •   Sam Holder Brian Adams    16 年前

    好吧,在玩了更多的游戏之后(也许只是把问题写下来帮助我更清楚地思考它),我想我已经找到了解决办法。

    看来我需要打电话给:

    RhinoMocksExtensions.Replay (foo);
    

    在我打电话之前

    Assert.IsTrue (foo.Method2 ());
    

    也许,当使用虚拟方法而不设定期望值时,需要明确地告知Rhino模拟。不知道为什么。如果有人知道这背后的原因,我很想知道。

    不管怎样,一切似乎都在工作,所以快乐的日子。