RhinoMock:如何使用复杂对象作为参数存根和返回方法

时间:2011-10-14 06:55:49

标签: mocking rhino-mocks stub

我非常感谢任何人都可以帮助我解决下面提到的问题: 我一直在单元测试中使用RhinoMock。 我以这种方式定义我的模拟对象,其中sessionToken是字符串类型的:

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

在调用 FindById()返回有效新的新DeviceTypeRepository()时,代码部分没问题.NewTable(false);

但是,当将一个复杂参数作为对象(如DataTable)包含到Stub中时,如下所示:

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

然后调用 Find()的代码部分, NOT 返回预期的新DeviceTypeRepository()。NewTable(false)。 请注意,参数dataTable的输入值在Stub和Find()调用中都是相同的。

因此,我的问题是: 我如何使用RhinoMock将这样的参数(DataTable类型化,更一般地)实现到Stub初始化中?我很感激任何建议和方法。 感谢

2 个答案:

答案 0 :(得分:9)

我认为问题不在于复杂的数据类型,而在于您设定的期望值。

首次尝试修复此问题时,请在IgnoreArguments()之前添加Return。可能是您在期望中指定的DataTable与实际传入的DataTable实例不同,因此期望不会通过:

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

如果没有帮助,您可以使用WhenCalled()手动调试它:

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

如果这样做无效,请尝试在Repeat().Any()之后添加Return(),看看它是否有效。我假设如果方法被调用了几次,你可能错过了第一个返回值,但我可能错了。

答案 1 :(得分:6)

如果它没有返回您期望的内容,那么存根调用和实际调用之间的参数不匹配。假设你有类似的东西:

// 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);

即使someDataTableanotherDataTable具有完全相同的内容,它们也不是同一个对象,当RhinoMocks将存根调用与实际调用进行比较时,参数不会比赛。你可以做的是使用约束:

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