繁体   English   中英

Jasmine 如何传递以依赖于闭包变量的任何顺序运行的规范

[英]Jasmine how pass specs that run in any order that depend on a closure variable

我觉得这应该是非常直观的......但也许它的工作方式与我在 Rspec 中习惯的想法不同......这是我正在尝试测试的 function:

var finalSet = (function() {
  var mount = false

  return {
    initializePage: function() {
      if (mount == false) {
        this.mountForm();
        mount = true;
      }
      this.greetCustomer();
    },
    greetCustomer: function() {
      ...
    },
    mountForm: function() {
      ...
    }
  }
})();

要点是mount是一个闭包变量,确保无论调用多少次initializePagemountForm只调用一次。

这是我目前的规格:

describe("finalSet", function() {
  describe("initializePage", function() {
    beforeEach(function() {
      spyOn(finalSet, "mountForm")
      spyOn(finalSet, "greetCustomer")
    })
    describe("first initialization", function() {
      beforeEach(function() {
        finalSet.initializePage();
      })
      it("calls both methods", function() {
        expect(finalSet.mountForm).toHaveBeenCalled()
        expect(finalSet.greetCustomer).toHaveBeenCalled()
      })
      describe("initialize again", function() {
        beforeEach(function() {
          finalSet.initializePage();
        })
        it("repeat calls only greetCustomer", function() {
          expect(finalSet.mountForm.calls.count()).toEqual(1)
          expect(finalSet.greetCustomer.calls.count()).toEqual(2)
        })
      })
    })
  })
})

如果我单独运行规范,它们就会通过。 一起随机地,只有一个会通过,第一个运行的规范,第二个总是失败。

我知道为什么会这样……但不是为解决此问题而设置的适当 Jasmine。

它发生的原因是因为finalSet在所有规范中安装一次,这意味着尽管有两个规范,但闭包设置一次。 所以如果"first initialization"测试先运行, beforeEachfinalSet.initializePage()的调用设置mount = true ,第一个规范通过,但是接下来, "initialize again" test, mount is still true, it doesn't reset, so neither of the 2 calls to will ever call mountForm`,因为这发生在第一个通过的规范中。 因此第二个规范失败了。

另一方面,如果"initialize again"先运行,堆叠的 2 个beforeEach调用finalSet.initializePage()将按预期工作, mountForm被调用一次, greetCustomer被调用两次。 但是当第一个"first initialization"规范被调用时, mount = true已经存在,所以什么都不会被调用。

直接的问题:有没有办法将闭包重置为第一个beforeEach的一部分?

更大的问题:我已经习惯了 Rspec 中的这种嵌套规范,但是......我觉得也许这不是在 Jasmine 中应该测试的方式,所以非常愿意接受更好的测试方法是。

谢谢!

您正在尝试跨多个规范测试本质上是全局 object 的内容。 您将以某种方式修改您的代码以测试您想要的内容。 这里有一些想法:

  1. 将 reset() function 添加到导出的 object 中,将 mount 变量设置为 false,在规范中的 before/afterEach 中调用此 function。 这类似于您在每次测试之前如何在 Rails 规范中重置数据库(全局资源)。

  2. 让您的代码返回 function 而不是立即调用它。 您可以将 finalSet 变量重命名为 createFinalSet。 这意味着您有一个 finalSet 工厂而不是全局实例或 singleton; 每个测试都会通过finalSet = createFinalSet()拥有自己的 finalSet。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM