6
votes

I highly appreciate anyone can help me in below-mentioned issue: I've been using RhinoMock in Unit Test. I define my mock object in such manner, with sessionToken is string-typed:

mockRepository.Stub(repository => repository.FindById(sessionToken)).Return(new DeviceTypeRepository().NewTable(false));

It's ok for the code section when calling FindById() to return the valid new new DeviceTypeRepository().NewTable(false);

However, when include a complex parameter as object, such as a DataTable, into the Stub as below:

mockRepository.Stub(repository => repository.Find(sessionToken, dataTable)).Return(new DeviceTypeRepository().NewTable(false));

Then the code section in which Find() is invoked, it does NOT return expected new DeviceTypeRepository().NewTable(false). Notice that input value of parameter dataTable is the same in both Stub and in Find() invocation.

Hence, my question is: How could I implement such parameter (DataTable typed and more generally) into Stub initialization using RhinoMock ? I'd be grateful to any advice and approach. Thanks

2
Is dataTable's value or reference the same in both Stub() and Find()? - Jeroen

2 Answers

9
votes

I believe the problem is not in a complex datatype but rather in the expectations you've set.

As a first attempt to fix it, add IgnoreArguments() before the Return. It could be that DataTable you've specified in expectation differs from the actually-passed-in DataTable instance so expectations won't pass:

...Stub(...).IgnoreArguments().Return();

If not helped you can debug it manually using WhenCalled():

...Stub(...).IgnoreArguments().WhenCalled(
    mi => 
    {
        var token = mi.Arguments[0] as TokenDataType;
        var dataTable = mi.Arguments[1] as DataTable;
    }).Return();

If that doesn't help, try to add Repeat().Any() after the Return() and see whether it works. I am supposing that if the method was called a few times, you may have missed the first return value, but I may be wrong.

6
votes

If it doesn't return what you'd expect, then the parameters between the stub call and the actual call don't match. Let's say you have something like this:

// Set expectations
var someDataTable = new DataTable(columns, raws);
mockRepository
   .Stub(repository => repository.Find(sessionToken, dataTable))
   .Return(new DeviceTypeRepository().NewTable(false));

// Actual test
var anotherDataTable = new DataTable(columns, raws);
yourTestObject.DoSomethingThatLooksForTheDataTable(repository);

The thing here that even though the someDataTable and anotherDataTable have the exact same content, they're not the same object and when RhinoMocks compare the stub call to the actual call the parameters don't match. What you can do is use constraints:

mockRepository
   .Stub(repository => repository.Find(
      Arg<SessionID>.Matches(y => y.ID == 2),
      Arg<DataTable>.Matches(x => x.Columns == columns && x.Raws == raws)
   ))
   .Return(true);