我目前正在使用Javascript进行一些TTD教程,并且我有一个似乎是Javascript而不是TTD问题。
即,我有以下测试:
'use strict';
var chai = require('chai');
var expect = chai.expect;
var sinon = require('sinon');
var orderSystemWith = require('../lib/orders');
//describe is used to display features
//context is used to display scenarios
//it is used to describe tests within a feature/scenario
describe('Customer displays order', function () {
beforeEach(function(){
this.orderDAO = {
byId: sinon.stub()
};
this.orderSystem = orderSystemWith(this.orderDAO);
})
context('Given that the order is empty', function(){
beforeEach(function(){
this.orderId = 'some empty order id';
this.orderDAO.byId.withArgs(this.orderId).returns([]);
this.result = this.orderSystem.display(this.orderId);
})
it('will show no order items', function(){
expect(this.result).to.have.property('items').that.is.empty;
});
it('will show 0 as the total prince', function(){
expect(this.result).to.have.property('totalPrice').that.is.equal(0);
});
it('will only be possible to add a beverage', function(){
expect(this.result).to.have.property('actions').that.is.deep.equal([{
action:'append-beverage',
target: this.orderId,
parameters: {
beverageRef: null,
quantity: 0
}
}])
});
});
});
orders.js
看起来像这样:
module.exports = function(orderDAO){
this.display = []
}
当我运行测试时,出现以下错误:
1) Customer displays order Given that the order is empty "before each" hook for "will show no order items": ReferenceError: orderSystem is not defined at Context.<anonymous> (test/customer_displays_order.js:22:27)
错误引用的行是这一行:
this.result = this.orderSystem.display(this.orderId);
有人能告诉我我做错了什么吗?在我看来,这是一个范围问题......
答案 0 :(得分:3)
在mocha中,描述块是对象。当您为this
分配内容时,我们的想法是为该对象分配属性。由于内部描述块(上下文块是同一个东西)正在创建一个新的上下文,它还没有导致它抛出的orderSystem
属性。
在内部块上使用箭头功能或绑定可能会解决您的问题。我倾向于发现当我有这样的嵌套块时,使用作用于外部块的变量有点干净。
答案 1 :(得分:2)
跟进@aaroncrows的回答:
通过使用词汇箭头函数(ES6构造),后续描述块的范围可以访问外部描述块的上下文(&#39; this&#39;)。这是带有词汇箭头功能的代码。
describe('Customer displays order', function () {
beforeEach( () => {
this.orderDAO = {
byId: sinon.stub()
};
this.orderSystem = orderSystemWith(this.orderDAO);
})
context('Given that the order is empty', () => {
beforeEach( () => {
this.orderId = 'some empty order id';
this.orderDAO.byId.withArgs(this.orderId).returns([]);
this.result = this.orderSystem.display(this.orderId);
})
it('will show no order items', () => {
expect(this.result).to.have.property('items').that.is.empty;
});
it('will show 0 as the total prince', () => {
expect(this.result).to.have.property('totalPrice').that.is.equal(0);
});
it('will only be possible to add a beverage', () => {
expect(this.result).to.have.property('actions').that.is.deep.equal([{
action:'append-beverage',
target: this.orderId,
parameters: {
beverageRef: null,
quantity: 0
}
}])
});
});
});
如果您不熟悉箭头功能,我强烈建议您进行更深入的解释。请注意,通过使用箭头功能,您的上下文(或&#39;此&#39;)指的是其内部的最高范围。在这种情况下,它是您描述块的匿名函数声明(即第一行代码)。但是,当访问这个&#39;在没有嵌套在功能块中的词法箭头函数中,您可能正在访问全局上下文(例如,如果您的代码在浏览器中执行,则为Window对象)。
希望有所帮助!