【问题标题】:Why use a Mocking Framework?为什么使用模拟框架?
【发布时间】:2011-07-04 16:56:09
【问题描述】:

我们目前使用 Autofac 作为 IoC 容器遵循 DI 模型。

我们最近开始研究 MOQ 和 Rhino Mocks 等模拟框架。但是,我们似乎无法证明使用它们来为我们的每个接口创建 Mock 实现类是合理的。

为什么这样做:

var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);

而不是这个:

class FooMock : IFoo {
  bool DoSomething(string input) {
    return input == "ping";
  }
}
mock = new FooMock();

后者更冗长,但似乎更灵活,更适合复杂的模拟。

【问题讨论】:

  • 这里有一个类似的问题可能会提供一些见解:stackoverflow.com/questions/300177/…
  • @Jason Down:我想说这不是一个“类似”的问题,而是同一个问题。投票以重复关闭。
  • @Don Roby:是的,我想这几乎是完全相同的问题。
  • 我一直觉得用DI来解析mocked对象比直接new一个mocked对象要好,因为mocked对象也可能有依赖关系,如果只使用mocking就必须手动设置,但是可以通过DI框架自动连线。

标签: c# .net mocking moq rhino-mocks


【解决方案1】:

您在示例中显示的更多的是假/存根,而不是真正的模拟,如果您只想要依赖对象的预先设定的行为,那么假通常可能比使用一个更好的选择模拟框架。

Martin Fowler 有一篇规范的文章讨论了 Mocks aren't Stubs 的事实,我从中删除了以下段落:

这里的关键区别在于我们如何 验证订单是否正确 事物在与 仓库。通过状态验证,我们 通过断言反对 仓库的状态。模拟使用行为 验证,我们改为检查 查看订单是否正确 调用仓库。

基本上使用模拟,您通常打算检查您的被测方法如何作用于依赖项 - 您的模拟具有预期,您在方法运行后验证这些预期。

当然,您仍然可以逐个模拟编写自己的案例,但使用框架会为您节省大量时间,提供更具可读性的测试并减少测试中的错误。

随着您的期望变得越来越复杂,这尤其正确,想象一下有一种方法来测试,该方法调用特定依赖类的次数可变,其值取决于输入参数 - 这将是复杂的编写一个模拟你自己,但使用一个好的模拟框架是微不足道的。

为了用一些代码进行演示,想象一下这个 PrintOrders 方法(请原谅这个愚蠢的例子):

public void PrintForeignOrders(List<Orders> orders)
{
    foreach(var order in orders)
    {
        if (order.IsForeign)
        {
            printer.PrintOrder(order.Number, order.Name);
        }
    }
}

你可能至少想测试一下:

  • 当列表为空时,不打印任何内容
  • 有国外订单时会打印出来
  • 当有两个订单时,都打印(使用正确的编号和名称)

有了一个好的模拟框架,对注入的打印机对象设置这些测试只需要敲几下键盘就可以了。

【讨论】:

    【解决方案2】:

    每次更改界面时,都必须调整每个手动编码的模拟对象(实际上是存根)以符合新界面。

    因此,每次更改接口时,拥有大量手工编码的存根对象将导致对测试代码进行大量维护。然而,由模拟框架创建的模拟将始终与更新后的界面兼容。

    【讨论】:

      【解决方案3】:

      但是,我们似乎无法证明 他们的用法不仅仅是创建 Mock 我们每个人的实现类 接口。

      这正是模拟框架可以让您免于做的事情 - 创建存根或模拟实现只是为了能够测试您的类的行为。

      无论如何,您所做的事情都没有错,如果对您的项目可行,请务必坚持下去——尽管对许多人来说,这似乎是一项非常平凡的任务,而这正是使用模拟的地方框架可以为您节省大量时间,还可以避免仅用于测试的代码库臃肿以及在您的模拟实现中出现其他错误的可能性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        • 1970-01-01
        • 2011-03-03
        • 1970-01-01
        • 2019-01-08
        • 1970-01-01
        相关资源
        最近更新 更多