【问题标题】:Rhino Mocks AAA Quick Start?Rhino Mocks AAA 快速入门?
【发布时间】:2011-01-08 14:41:40
【问题描述】:

我一直在寻找一些关于使用带有 AAA 语法的 Rhino Mocks 3.5+ 的体面信息。我发现很多博客都混合了新旧事物,这似乎使弄清楚如何使用它变得更加困难。

如果有像早期版本那样的 Rhino Mocks AAA 备忘单,那就太好了。是否需要您了解有关旧版本 Rhino 的所有信息才能实际使用新版本?我敢肯定,如果我是专家,我会喜欢 Rhino 的所有功能,但现在我只是在信息中游泳。任何指针或良好的链接将不胜感激!

【问题讨论】:

    标签: c# unit-testing rhino-mocks arrange-act-assert


    【解决方案1】:

    我写了一个Rhino Mocks Arrange / Act / Assert (AAA) Syntax Quick Reference。它包含从Ayende's web site 和其他几个博客收集的有关此语法样式的浓缩信息。

    【讨论】:

    • +1:不错的快速参考。我喜欢。相当齐全。理解这些概念可能不是一个好的开始,但记住语法并看看有什么可能是很棒的。
    【解决方案2】:

    我假设您熟悉official documentation,我认为这非常好。 我的建议是尝试使用 Rhino,当你遇到一些更具体的问题时,在 SO 或其他地方搜索解决方案。我不认为 Rhino 模拟有一个全面的备忘单。我想你会更幸运地问“我如何使用 Rhino Mocks 做到这一点和那个”

    编辑: 好吧,当你定位 AAA 时,你不需要使用 Record/Playback。 AAA 涉及​​三个步骤:

    • Arrange,代表设置 模拟类的行为,例如

    .

    IOmicronDll mockWrapper = MockRepository.GenerateMock<IOmicronDll>();
    mockWrapper.Expect(wrapper => wrapper.Lock(1, ref errors)).OutRef(string.Empty).Return(true).Repeat.Any();
    mockWrapper.Expect(wrapper => wrapper.Exec(1, "sys:cfg?(type)", ref output, ref errors)).OutRef("1,CMC 56,0;", "").Return(true).Repeat.Any();
    mockWrapper.Expect(wrapper => wrapper.Exec("1", "sys:cfg?(type)", ref output, ref errors)).OutRef("1,CMC 56,0;", "").Return(true).Repeat.Any();
    Microsoft.Practices.Unity.UnityContainer c = new Microsoft.Practices.Unity.UnityContainer();
    c.RegisterInstance<IOmicronDll>(mockWrapper);
    
    • Act,代表执行测试

      public Omicron(int deviceID)
      {
          try
          {
              if (g_Omicron == null)
                  g_Omicron = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<CMEngineWrapper.IOmicronDll>();
              m_UniqueIdentifier = Guid.NewGuid();
              m_Logger = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<AdvAdmittance.Framework.ILogger>();
              m_ID = deviceID;
              GetConfiguration();
              g_InstancesCount++;
              m_PollThread = new Thread(new ThreadStart(DoPoll));
              m_PollThread.Start();
          }
      
    • 还有Assert,代表veryfing 结果

    .

    Assert.AreEqual("CMC 56", omicron.Type);
    mockWrapper.AssertWasCalled(wrapper => wrapper.Release(), options => options.Repeat.AtLeastOnce());
    

    也许上面的例子不是最好的,但可能会让你进入正确的方向。

    【讨论】:

    • 谢谢,是的 - Ayende 肯定有一些很棒的东西。就像一个想要学习如何用 Rhino 做 AAA 级的新手一样,我似乎需要使用 Record/Playback 来做这件事,然后作为具体问题如何做 AAA 风格?当然,我必须先学习录制/播放。这就是为什么我不知道从哪里开始问一个好问题。
    • 我的建议是完全跳过录制/播放。我认为 AAA 语法更简洁、更容易理解,而且您实际上不需要知道过去使用 R/P 是如何完成的。从编写一些简单的单元测试开始,并按照您认为 Rhino 的工作方式进行断言。然后,这将帮助您练习 AAA 语法。
    • -1 AAA 的想法是您在开始时设置具有行为的存根,并在结束时进行断言(如您链接到的文档中所示)。但是您使用的是模拟而不是存根,您在一开始就设定了期望,而期望甚至从未得到验证,因为您没有在任何地方使用VerifyAllExpectations。从比尔的这个后续问题中可以明显看出你让他感到困惑:stackoverflow.com/questions/2349454/rhinomocks-aaa-syntax/…
    • @Wim Coenen - 如果你看看他的期望,他有 Repeat.Any() 这意味着不需要调用 VerifyAllExpectations()。
    【解决方案3】:

    首先确保您了解 AAA 中每个 A 的含义。您可能知道,但我将包括我的工作定义以确保答案的完整性:

    • Arrange 是我设置输入、模拟/存根、带有被测方法的对象的地方
    • Act 是我调用被测方法的地方
    • Assert 是我验证事情是否按照预期发生或没有发生的地方

    我喜欢将 cmets 放入我的测试代码中,以提醒我考虑这些事情。一个例子可能有助于澄清:假设我有一个服务层类,它使用两个提供者层类,一个来自“旧”系统,一个来自“新”系统;我正在测试将旧事物复制到新系统的方法会为找到的每个旧事物调用一次“CreateThing”方法。

    [Test]
    public void Should_create_new_Thing_for_each_old_Thing()
    {
      // -----
      // arrange
    
      // hardcode results from old system provider
      List<Thing> oldThings = new List<Thing> { ... };
    
      // old system provider
      var oldProvider = MockRepository.GenerateStub<IOldSystemProvider>();
      oldProvider.Stub(m=>m.GetThings()).Return(oldThings);
    
      // new system provider
      var newProvider = MockRepository.GenerateStub<INewSystemProvider>();
    
      // service object
      var svc = new MyService(oldProvider, newProvider);
    
      //-----------
      // act
      var result = svc.CopyThings();
    
      //------------
      // assert
      oldThings.ForEach(thing => 
                        newProvider.AssertWasCalled(prov => prov.CreateThing(thing)));
    }
    

    【讨论】:

      【解决方案4】:

      您可能希望从Ayende's original post on AAA 开始,而不是查看Ben Hall's nice blog post about AAA。比您可以使用其他答案中提到的所有完整参考资料...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        • 1970-01-01
        • 2014-11-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多