2013-10-25 15 views
1

我目前正在用rhino mocks创建一些单元测试,我有一个如下所示的测试。不过,我不断收到此错误信息,我们如何让lambda函数在Rhino Mock对象的一部分的方法中执行?

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

这是由于未在_dispatcher.BeginInvoke(()=>_osgController.AddWindow)执行的lambda函数。如何使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()); 
    } 
} 

回答

1

为什么不被在测试执行lambda函数的原因是如下:

有2个lambda表达式:

  1. 该一个在测试方法中声明:

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

    () => _osgController.AddWindow() 
    

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

希望有所帮助。

0

对于错误消息:

犀牛嘲笑告诉你Expected #1, Actual #0。所以它预计AddWindow被调用一次,但它根本没有被调用。

,你必须建立一个的期望是:

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

至于是什么问题:

你的方法在调度程序被调用。此线程未在测试框架中运行,因此您必须创建一个才能运行测试。

有关如何设置此示例的示例,您可以看到DispatcherTimer doesn't work in Console

+0

感谢您的回复。它实际上是已注入的IDispatcher接口,而不是您正在考虑的WPF应用程序调度程序。问题是传递给BeginInvoke方法的lambda函数没有被执行。 – Seth

相关问题