我们如何在作为Rhino Mock对象一部分的方法中执行lambda函数?

时间:2013-10-25 04:02:35

标签: c# rhino-mocks

我目前正在使用rhino mocks创建一些单元测试,我有一个如下所示的测试。但是我一直收到此错误消息,

IOsgController.AddWindow(Whiteboard.Model.OsgWindowProps); Expected #1, Actual #0.

这是由于lambda函数未在_dispatcher.BeginInvoke(()=>_osgController.AddWindow)中执行。如何在单元测试中执行此Action

public void the_load_command_is_triggered_which_executes_the_load_control_method()
{
       // arrange
        IOsgController osgController = MockRepository.GenerateMock<IOsgController>();
        IDispatcher dispatcher = MockRepository.GenerateMock<IDispatcher>();
        Action action = osgController.AddWindow;
        OsgViewModel osgViewModel = new OsgViewModel(osgController, dispatcher);

        // dispatcher and add window should be called in LoadControl
        dispatcher.Expect(d => d.BeginInvoke(action)).WhenCalled(i => action());
        osgController.Expect(x => x.AddWindow());

        // act
        osgViewModel.LoadCommand.Execute(new object());

        // assert
        osgController.VerifyAllExpectations();
}

被测试的课程是:

public class OsgViewModel : ViewModelBase
{
    private readonly IOsgController _osgController;
    private readonly IDispatcher _dispatcher;

    public OsgViewModel(IOsgController osgController, IDispatcher dispatcher)
    {
        _osgController = osgController;
        _dispatcher = dispatcher;
        LoadCommand = new RelayCommand(LoadControl);
    }

    public ICommand LoadCommand { get; set; }

    public void LoadControl()
    {
        // lambda is not being executed in unit test.
        _dispatcher.BeginInvoke(
            () => _osgController.AddWindow());
    }
}

2 个答案:

答案 0 :(得分:1)

在测试中未执行lambda函数的原因如下:

有2个lambdas:

  1. 以测试方法声明的那个:

    Action action = osgController.AddWindow;
    
  2. 在被测试的班级中声明的另一个:

    () => _osgController.AddWindow()
    
  3. 他们做的完全相同,但他们是不同的 这就是dispatcher.Expect(d => d.BeginInvoke(action))的设置与传递给BeginInvoke()的实际操作不匹配的原因。因此,WhenCalled()参数未被触发。

    其中一个解决方案是设置dispatcher.BeginInvoke()的存根,它接受任何操作并执行它:

     dispatcher
        .Stub(d => d.BeginInvoke(Arg<Action>.Is.Anything))
        .WhenCalled(opt => ((Action)(opt.Arguments[0]))());
    

    此外,可以使用Do()处理程序代替WhenCalled()。然后不需要参数演绎:

     dispatcher
        .Stub(d => d.BeginInvoke(Arg<Action>.Is.Anything))
        .Do((Action<Action>)(action => action()));
    

    希望有所帮助。

答案 1 :(得分:0)

对于错误消息:

Rhino Mocks告诉你Expected #1, Actual #0。因此,它希望调用AddWindow一次,但根本不会调用它。

您设置的一个期望是:

osgController.Expect(x => x.AddWindow(osgViewModel.WindowProperties));

至于问题所在:

您的方法正在Dispatcher中调用。此线程未在测试框架中运行,因此您必须创建一个以运行测试。

您可以查看DispatcherTimer doesn't work in Console有关如何设置此内容的示例。