Stubbing a Property get using Rhino Mocks

Santhosh picture Santhosh · Aug 9, 2011 · Viewed 22.8k times · Source

Using RhinoMocks, I am trying to Stub the getter value of a property. The property is defined as part of a Interface with only getter access.

However I get the error "Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method)." I understand this may mean that the property I am stubbing is not virtual; However it is part of the Interface and I am not sure if that is the reason why I get this error..

Below is the code skeleton. If I uncomment the line which says "stubRepository.Stub(x => x.StoreDeviceID).PropertyBehavior();", then I get a new error "Property must be read/write". I searched on SO and found this page. But the proposed solution doesn't help me. Any thoughts?

public interface IStore {
        string StoreDeviceID {get;}
        //other methods
    }

    public static class Store {
        private IStore Repository;

        public void SetRepository(IStore rep){
            Repository = rep;
        }

        public StoredeviceID {
            get{
                return Repository.StoreDeviceID;
            }
        }

        //other methods
    }

    public class TestClass {
        [Test]
        public void TestDeviceID() {
            var stubRepository =
                MockRepository.GenerateStub<IStore>();
            Store.SetRepository(stubRepository);

            //stubRepository.Stub(x => x.StoreDeviceID).PropertyBehavior();
            SetupResult.For(stubRepository.StoreDeviceID).Return("test");

            Assert.AreSame(Store.StoreDeviceID, "test");
        }
    }

Answer

Adam Rackis picture Adam Rackis · Aug 9, 2011

Since this is a read only property, you need to say:

stubRepository.Stub(x => x.StoreDeviceID).Return("test");

Normally with stubs, properties are used like normal C# properties. So for non-readonly properties, you would say: stubRepository.someProperty = "test";

Also note that if you wanted to set up a method to behave a certain way, regardless of whether it's a mock or a stub, you would always say:

stubRepository.Stub(x => x.someMethod()).Return("foo");

Remember, stubs are there to supply your unit tests with their needed dependencies, but are not there to run verifications on; that's what mocks are for.

Use a stub when you want to supply a dependency that behaves a certain way. Use a Mock when you want to verify that a certain dependency has been interacted with correctly.

From the (outstanding) Rhino Wiki:

A mock is an object that we can set expectations on, and which will verify that the expected actions have indeed occurred. A stub is an object that you use in order to pass to the code under test. You can setup expectations on it, so it would act in certain ways, but those expectations will never be verified. A stub's properties will automatically behave like normal properties, and you can't set expectations on them.

If you want to verify the behavior of the code under test, you will use a mock with the appropriate expectation, and verify that. If you want just to pass a value that may need to act in a certain way, but isn't the focus of this test, you will use a stub.

IMPORTANT: A stub will never cause a test to fail.