【问题标题】:How to assert that an action was called如何断言一个动作被调用
【发布时间】:2011-06-20 14:46:10
【问题描述】:

我需要资产一个由模拟组件调用的操作。

 public interface IDispatcher
    {
     void Invoke(Action action);
    }

    public interface IDialogService
    {
      void Prompt(string message);
    }

    public class MyClass
    {
    private readonly IDispatcher dispatcher;
    private readonly IDialogservice dialogService;
    public MyClass(IDispatcher dispatcher, IDialogService dialogService)
    {
     this.dispatcher = dispatcher;
    this.dialogService = dialogService;
    }

    public void PromptOnUiThread(string message)
    {
     dispatcher.Invoke(()=>dialogService.Prompt(message));
    }
    }

    ..and in my test..

   [TestFixture]
    public class Test
    {
     private IDispatcher mockDispatcher;
     private IDialogService mockDialogService;
    [Setup]
    public void Setup()
    {
     mockDispatcher = MockRepository.GenerateMock<IDispatcher>();
     mockDialogService = MockRepository.GenerateMock<IDialogService>();
    }

    [Test]
    public void Mytest()
    {
     var sut = CreateSut();
    sut.Prompt("message");

    //Need to assert that mockdispatcher.Invoke was called
    //Need to assert that mockDialogService.Prompt("message") was called.
    }
     public MyClass CreateSut()
    {
      return new MyClass(mockDipatcher,mockDialogService);
    }
    }

也许我需要重组代码,但对此感到困惑。可以请教吗?

【问题讨论】:

    标签: c# tdd rhino-mocks


    【解决方案1】:

    你实际上是在测试这行代码:

    dispatcher.Invoke(() => dialogService.Prompt(message));
    

    您的类调用模拟来调用另一个模拟上的方法。这通常很简单,您只需要确保使用正确的参数调用 Invoke。不幸的是,这个论点是一个 lambda 并且不那么容易评估。但幸运的是,这是对 mock 的调用,这又使它变得容易:只需调用它并验证另一个 mock 是否已被调用:

    Action givenAction = null;
    mockDipatcher
      .AssertWasCalled(x => x.Invoke(Arg<Action>.Is.Anything))
      // get the argument passed. There are other solutions to achive the same
      .WhenCalled(call => givenAction = (Action)call.Arguments[0]);
    
    // evaluate if the given action is a call to the mocked DialogService   
    // by calling it and verify that the mock had been called:
    givenAction.Invoke();
    mockDialogService.AssertWasCalled(x => x.Prompt(message));
    

    【讨论】:

    • 我相信是 mockDipatcher .Expect(x => x.Invoke(Arg.Is.Anything)) // 让参数通过。还有其他解决方案可以实现相同的 .WhenCalled(call => givenAction = (Action)call.Arguments[0]);
    • 您可以将WhenCalledExpectStubAssertWasCalled 结合使用:-)
    【解决方案2】:

    您首先需要对您的模拟设置一个期望。例如我想测试 Invoke 只被调用一次并且我不关心传入的参数。

    mockDispatcher.Expect(m => m.Invoke(null)).IgnoreArguments().Repeat.Once();
    

    然后你必须断言并验证你的期望

    mockDispatcher.VerifyAllExpectations();
    

    您可以对第二个模拟以相同的方式执行此操作,但是每个单元测试有两个模拟不是一个好习惯。您应该在不同的测试中测试每个。

    有关设定期望,请阅读http://ayende.com/wiki/Rhino+Mocks+Documentation.ashx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 2018-02-25
      相关资源
      最近更新 更多