Search code examples
c#silverlightunit-testingrhino-mocks

Mocking InvokeOperation for Unit Testing using Rhino Mocks


I have a Data Service interface with a method:

   void GetDataByLocationId(Guid locationId, Action<InvokeOperation<IEnumerable<DataValue>>> callback);

I want to test a class that depends on this data service interface, and would like to mock out the above method.

I set up my mocks as:

_mocks = new MockRepository();

    var dataLoadOperation = _mocks.StrictMock<InvokeOperation<IEnumerable<DataValue>>>();
    Action<InvokeOperation<IEnumerable<DataValue>>> dataValueCallback = null;

Then in my test execution:

    var locationId = Guid.NewGuid();
    var values = // something //
    using (_mocks.Unordered())
    {
            Expect.Call(() => _dataService.GetDataByLocationId(Arg<Guid>.Is.Equal(locationId), Arg<Action<InvokeOperation<IEnumerable<DataValue>>>>.Is.Anything));
            LastCall.Callback(new Func<Action<InvokeOperation<IEnumerable<DataValue>>>, bool>(c => { dataValueCallback = c; return true; }));
            dataLoadOperation .Stub(x => x.HasError).Return(false);
            dataLoadOperation .Stub(x => x.Value).Return(values);
    }

But it never makes it to the execution... It turns out that:

System.ServiceModel.DomainServices.Client.InvokeOperation

Is a sealed class, and Rhino Mocks throws an Exception when running

Can't create mocks of sealed classes

I am looking for suggestions on improving my design to support this test case; and still using mocks.


Solution

  • I would create an interface that represents your interaction with the InvokeOperation class. Create a "default" implementation that simply delegates to the real InvokeOperation class. You can then stub out the interface during mocking.

    The interface doesn't need to be a full copy of InvokeOperation's members and properties -- just the ones you use in your application.