1

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

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());
    }
}
4

2 回答 2

1

测试中没有执行 lambda 函数的原因如下:

有 2 个 lambda:

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

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

    () => _osgController.AddWindow()
    

他们做的完全一样,但他们是不同的。
这就是为什么 setup fordispatcher.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()));

希望有帮助。

于 2013-10-27T07:42:29.577 回答
0

对于错误消息:

犀牛模拟告诉你Expected #1, Actual #0。所以它期望AddWindow被调用一次,但它根本没有被调用。

您设置的一个期望是:

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

至于问题是什么:

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

您可以看到DispatcherTimer 在控制台中不起作用,以了解如何设置它的示例。

于 2013-10-25T04:13:35.217 回答