如何在coffeescript中的特定范围内声明变量?

Kev*_*son 38 coffeescript jasmine

我正在尝试在coffeescript中编写一个使用beforeEach块的茉莉花测试.这遇到了coffeescript的变量范围问题.这是我想写的:

describe 'PhoneDetailCtrl', () ->
  beforeEach () ->
    scope = angular.scope()
    $browser = scope.$service('$browser')

  it 'should fetch phone detail', () ->
    scope.params = {phoneId:'xyz'}
    $browser.xhr.expectGET('phones/xyz.json').respond({name:'phone xyz'})
    ctrl = scope.$new(PhoneDetailCtrl)

    expect(ctrl.phone).toEqualData({})
    $browser.xhr.flush()

    expect(ctrl.phone).toEqualData({name:'phone xyz'})
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为scope$browservar在最里面的范围内声明.也就是说,一旦进入beforeEach,然后又在it块中.我可以通过初始化来强制在正确的范围内声明变量,但这看起来很奇怪:

describe 'PhoneDetailCtrl', () ->
  $browser = {}
  scope = {}
  beforeEach () ->
    scope = angular.scope()
    $browser = scope.$service('$browser')

  it 'should fetch phone detail', () ->
    scope.params = {phoneId:'xyz'}
    ...
Run Code Online (Sandbox Code Playgroud)

这可行,但它编译的JavaScript实际上是

describe('PhoneListCtrl', function() {
  var $browser, ctrl, scope;
  $browser = {};
  ctrl = {};
  scope = {};
Run Code Online (Sandbox Code Playgroud)

我需要的只是线var $browser, ctrl, scope;.我可以在coffeescript中更简洁地写出这个吗?

Bri*_*sio 30

你正在以正确的方式做到这一点.

这在CoffeeScript文档中有所描述.我不担心它创建的JS.是的,如果您自己编写它会有点麻烦,但这是您使用像CoffeeScript这样的重写器时必须要考虑的事情之一.

但是,你有几个非常好的选择.

你可以把变量放在当前的上下文中(这恰好是你的jasmine.Spec对象的好奇,所以它是一个相对安全和适当的地方放置变量...只是不要覆盖现有的变量上下文.):

describe 'PhoneDetailCtrl', () ->
  beforeEach () ->
    @scope = angular.scope()
    @$browser = @scope.$service('$browser')

it 'should fetch phone detail', () ->
  @scope.params = {phoneId:'xyz'}
  #... etc
Run Code Online (Sandbox Code Playgroud)

您还可以设置自己的变量来存储内容

describe 'PhoneDetailCtrl', () ->
  setup = {}

  beforeEach () ->
    setup.scope = angular.scope()
    setup.$browser = setup.scope.$service('$browser')

  it 'should fetch phone detail', () ->
    setup.scope.params = {phoneId:'xyz'}
    #... etc
Run Code Online (Sandbox Code Playgroud)


Fel*_*awa 10

您的测试可以写成如下:

describe "MyGame", ->
    mygame = null
    beforeEach inject (_MyGame_) ->
        mygame = _MyGame_

    it "should have two players", ->
        expect(mygame.opponents.length).toEqual 2
Run Code Online (Sandbox Code Playgroud)

更清晰的语法 - 无需使事物全局化.

  • 你也可以使用`a = b = c = d = null`作为备用线路.变量不会相互影响(相反,如果你将它们分配给`{}`) (4认同)