问题 Rhino Mocks AAA快速入门?


我一直在寻找有关使用Rhino Mocks 3.5+和AAA语法的一些不错的信息。我发现很多博客都混合了旧的和新的东西,似乎更难以弄清楚如何使用它。

如果有一个像早期版本那样的Rhino Mocks AAA Cheat Sheet,那将会很棒。您是否需要了解有关旧版Rhino的所有内容才能真正使用新版本?我敢肯定,如果我是专家,我会喜欢Rhino的所有功能,但现在我只是在游泳信息。任何指针或良好的链接将完全赞赏!


8603
2018-01-23 18:24


起源



答案:


我写了一篇 Rhino Mocks Arrange / Act / Assert(AAA)语法快速参考。它包含有关从中收集的此语法样式的精简信息 Ayende的网站  和其他几个博客。


13
2018-03-28 21:19



+1:很好的快速参考。我喜欢。相当完整。理解这些概念可能不是一个好的开始,但是记住语法并看看有什么可能是很好的。 - Stefan Steinegger


答案:


我写了一篇 Rhino Mocks Arrange / Act / Assert(AAA)语法快速参考。它包含有关从中收集的此语法样式的精简信息 Ayende的网站  和其他几个博客。


13
2018-03-28 21:19



+1:很好的快速参考。我喜欢。相当完整。理解这些概念可能不是一个好的开始,但是记住语法并看看有什么可能是很好的。 - Stefan Steinegger


我假设你很熟悉 官方文件,在我看来这是相当不错的。 我的建议是尝试使用Rhino,当你遇到一些更具体的问题时,搜索SO或其他地方的解决方案。我不认为有一个全面的犀牛嘲笑备忘单。我想你会有更多的运气问“我怎么能用犀牛模拟做到这一点”

编辑: 那么,在定位AAA时,您不需要使用录制/播放。 AAA涉及三个步骤:

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

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);
  • 法案,代表执行测试

    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.AreEqual("CMC 56", omicron.Type);
mockWrapper.AssertWasCalled(wrapper => wrapper.Release(), options => options.Repeat.AtLeastOnce());

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


1
2018-01-25 08:29



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


首先要确保你知道你对AAA中每个A的意思。您可能知道,但我会将我的工作定义包含在答案的完整性中:

  • 安排 是我设置输入,模拟/存根,使用被测方法的对象的地方
  • 法案 是我称之为测试方法的地方
  • 断言 是我根据期望验证发生或未发生事情的地方

我喜欢在我的测试代码中添加注释,以提醒我考虑每一个问题。一个例子可能有助于澄清:假设我有一个服务层类,它使用两个提供者层类,一个来自“旧”系统,另一个来自“新”系统;我正在测试将旧东西复制到新系统的方法为每个找到的旧东西调用一次“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)));
}

1
2017-07-12 17:48





你可能想要开始 Ayende在AAA上的原始帖子,而不是看看 Ben Hall关于AAA的好文章。你可以使用其他答案中提到的所有完整参考资料......


1
2017-09-22 20:23