使用RhinoMock进行单元测试:在预期的调用语句中从CuT调用方法

时间:2012-06-08 08:06:26

标签: c# unit-testing rhino-mocks

实际上我正在编写单元测试,为此我使用RhinoMocks。

TestMethod的:

{
   ...
   var classA = repo.StrictMock<IMyInterface>();
   Expect.Call(()=>classA.AddItem()). // call here method cuT.ItemAdded()
   repo.ReplayAll();

   // test
   cuT.DoSomething(classA);

   ...
}

待测班级:

{
   ...
   public void DoSomething(IMyInterface myInterface)
   {
      myInterface.AddItem();
   }

   public void ItemAdded(object sender, ItemEventArgs e)
   {
     UpdateModel(); // update model only if item wasn't added by AddItem() method called from DoSomething()..
     ...
   }
}

我的问题是,我如何定义Expect.Call()语句,以便通过在接口上调用预期的方法AddItem()来引发对cuT.ItemAdded()的调用。

提前感谢您的帮助!

此致 rhe1980

1 个答案:

答案 0 :(得分:0)

你真正想要的是两个测试,因为使用事件表明添加项目可能来自不同的来源(而不是DoSomething方法):

// 1: This test will simply verify that tested method calls dependency
public void DoSomething_AddsItemOnMyInterface()
{
    var myInterface = MocksRepository.GenerateMock<IMyInterface>();
    myInterface.Expect(m => m.AddItem()).Repeat.Once();

    cut.DoSomething(myInterface);

    myInterface.VerifyAllExpectations();
}

// 2: Here we assure that model gets updated when item was added
public void ItemAdded_UpdatesModel_WhenMyInterfaceRaisesEvent()
{
    var myInterface = MocksRepository.GenerateMock<IMyInterface>();
    myInterface.Expect(m => m.AddItem()).Repeat.Once();

    myInterface.Raise(m => m.ItemAddedEvent += null, myInterface,
        new ItemEventArgs());

    // How exactly model is updated when event is raised? The 'how'
    // should be asserted here.
}

例如,如果UpdateModel将您的类属性设置为某个值,则可以断言。如果它正在清除一些集合,那么断言你会检查该集合是否为空。从测试的角度来看,事件本身并不有趣(将其视为条件);当引发该事件时, 合同)会发生什么?并且测试应检查签约的确实发生了什么

顺便说一下,你使用的语法(Record-Replay)有点旧。 Rhino现在支持更流畅的Arrange-Act-Assert语法(使用ExpectStubVerify方法。更多内容可以在维基页面here找到。