在Arrange-Act-Assert测试样式中,将Act移动到beforeEach / setUp块中是否可以?

时间:2014-12-22 15:38:02

标签: unit-testing jasmine arrange-act-assert

当从单个逻辑操作单元测试结果和/或副作用时,如何保持代码干?以下以Jasmine编写的示例为例:

describe("frobnicate", function () {
  var foo;

  beforeEach(function () {
    foo = getFoo();
  });

  it("causes side-effect 1", function () {
    frobnicate(foo);

    expect(sideEffect1).toEqual('you did it');
  });

  it("causes side-effect 2", function () {
    frobnicate(foo);

    expect(sideEffect2).toHaveBeenCalled();
  });

  /* side effect 3, 4, etc. */
});

注意重复的Act,调用frobnicate(foo)。使用允许嵌套描述上下文(例如Jasmine)的单元测试框架,按照以下方式重构测试似乎很自然:

describe("frobnicate", function () {
  beforeEach(function () {
    var foo = getFoo();

    frobnicate(foo);
  });

  it("causes side-effect 1", function () {
    expect(sideEffect1).toEqual('you did it');
  });

  it("causes side-effect 2", function () {
    expect(sideEffect2).toHaveBeenCalled();
  });

  /* test side effect 3, 4, etc. */
});

这种风格是否与AAA测试风格相矛盾?以这种方式重构代码会引发其他问题吗?

2 个答案:

答案 0 :(得分:3)

这不仅与Arrange-Act-Assert相矛盾,而且我会坚持你这样做。测试中的重复是主要的维护问题之一,应尽可能地进行删除。

要求复制的最大问题是"如果这会发生变化会发生什么?",如果你必须在多个地方进行更改,那么重构。

答案 1 :(得分:1)

不,不行。是的,将法案置于设置步骤确实会引发问题,或暗示您可能已经走上了一条有问题的道路。

人们通常希望这样做,因为他们认为每次测试只允许一个断言。他们发现测试给定的Arrange和Act组合需要不止一个断言,因此他们为每个断言编写一个测试。现在,Arrange-Act组合被复制,因此他们将其移动到设置步骤中。但现在他们遇到了新问题:

  • 以这种方式编写的测试通常需要大量的语法来说明通过将所有断言放在同一个测试中更简单的说法。

  • 如果安排和/或行动需要任何时间来运行,现在有许多慢速测试,而不只是一个。

  • 我使用过的所有测试框架都称之为“之前”,“setUp”等设置步骤,毫无疑问,因为他们的作者正在考虑使用这些步骤进行安排,而不是行动。如果您正在尝试编写阅读良好的测试,那么这种矛盾的语言就会变得不和谐。

因此,我通常会为每个不同的Arrange-Act对编写一个测试,并在该测试中使用尽可能多的断言。