views:

346

answers:

2

Could someone explain why both tests using the latest versions of Moq and Rhino.Mocks frameworks fail complaining that Bar is not a virtual/overridable method:

public interface IFoo
{
    string Bar();
}

public class Foo : IFoo
{
    public string Bar()
    {
        return "Bar";
    }
}

[TestMethod]
public void MoqTest()
{
    var foo = new Mock<Foo>();
    foo.Setup(f => f.Bar()).Returns("abc");
    Assert.AreEqual("abc", foo.Object.Bar());
}

[TestMethod]
public void RhinoTest()
{
    var foo = new MockRepository().PartialMock<Foo>();
    foo.Expect(f => f.Bar()).Return("abc");
    foo.Replay();
    Assert.AreEqual("abc", foo.Bar());
}

If I declare Bar method as virtual both tests pass. I don't understand why I have to declare Bar as virtual. Isn't it already virtual? It comes from the interface.

+1  A: 

Because you're mocking Foo class. Mock IFoo intefrace instead

var foo = new MockRepository().PartialMock<IFoo>();
Krzysztof Koźmic
Yes, that's correct. In fact I have another method in the Bar class that's not virtual and it's calling Bar. It's this method that I am testing and I want to mock the call to Bar.
Darin Dimitrov
So my original question remains. I know that it doesn't cost much to add virtual to the declaration of Bar but I was just wondering why both frameworks behave this way. There must be some reason behind this behavior.
Darin Dimitrov
+4  A: 

Virtual is part of the class not the interface, so if you wish to override the method on the class Foo you will need to declare it as virtual.

However as Krzysztof mentions if all you need are the methods on the interface IFoo then you should mock the interface.

confusedGeek
I don't see why I have to declare it virtual? I can perfectly override the Bar method in a descendant class without declaring Bar as virtual.
Darin Dimitrov
You can't (at least not in C# - you can in Java). In C#, all you can do is redeclare Bar using the new keyword.
petr k.
You are perfectly right. I apologize for my complete ignorance. Now I understand.
Darin Dimitrov