我正在尝试在coffeescript中编写一个使用beforeEach块的jasmine测试。这遇到了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'})
但这不起作用,因为scope
和$browser
将在最里面的范围内以var
声明。也就是说,一旦进入beforeEach
,然后再进入it
区块。我可以通过初始化来强制在正确的范围内声明变量,但这看起来很奇怪:
describe 'PhoneDetailCtrl', () ->
$browser = {}
scope = {}
beforeEach () ->
scope = angular.scope()
$browser = scope.$service('$browser')
it 'should fetch phone detail', () ->
scope.params = {phoneId:'xyz'}
...
这样可行,但它编译的javascript实际上是
describe('PhoneListCtrl', function() {
var $browser, ctrl, scope;
$browser = {};
ctrl = {};
scope = {};
我需要的只是行var $browser, ctrl, scope;
。我可以在coffeescript中更简洁地写这个吗?
答案 0 :(得分:30)
你正在以正确的方式做到这一点。
CoffeeScript documentation中对此进行了描述。我不担心它创建的JS。是的,如果您自己编写它会有点麻烦,但这是您使用像CoffeeScript这样的重写器时必须要考虑的事情之一。
然而,你确实有几个非常好的选择。
如果你愿意,你可以把变量放在当前的上下文中(恰好是你的jasmine.Spec对象好奇,所以它是一个相对安全和适当的地方放置变量......只是不要覆盖existing vars in the context):
describe 'PhoneDetailCtrl', () ->
beforeEach () ->
@scope = angular.scope()
@$browser = @scope.$service('$browser')
it 'should fetch phone detail', () ->
@scope.params = {phoneId:'xyz'}
#... etc
您还可以设置自己的变量来存储内容
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
答案 1 :(得分:10)
您的测试可以写成如下:
describe "MyGame", ->
mygame = null
beforeEach inject (_MyGame_) ->
mygame = _MyGame_
it "should have two players", ->
expect(mygame.opponents.length).toEqual 2
更清晰的语法 - 无需使事物全局化。