В настоящее время я просматриваю некоторые обучающие программы TTD с использованием Javascript, и у меня есть то, что кажется 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);
Может ли кто-нибудь сказать мне, что я делаю неправильно? Мне кажется, что это вопрос сферы...
В мокко описываемые блоки являются объектами. Когда вы назначаете что - то this
идея состоит в том, чтобы присвоить свойство этого объекта. Поскольку внутренний блок описания (контекст блокирует его одно и то же) создает новый контекст, он еще не имеет свойства orderSystem
которое вызывает его.
Использование функций стрелок или привязка во внутреннем блоке может решить вашу проблему. Я имею тенденцию находить, когда у меня есть вложенные блоки, подобные этому, используя переменные, привязанные к внешнему блоку, немного чище.
Чтобы следить за ответом от @aaroncrows:
Используя лексические функции стрелок (конструкция ES6), объем ваших последующих блоков описания может иметь доступ к контексту вашего внешнего блока описания ("это"). Здесь действует ваш код с лексической стрелкой.
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
}
}])
});
});
});
Если вы не знакомы со стрелочными функциями, я бы настоятельно рекомендовал вам использовать некоторые более глубокие объяснения. Имейте в виду, что с помощью функций стрелок ваш контекст (или "это") относится к самой верхней области, внутри которой он находится. В этом случае это описание объявления анонимной функции блока (т.е. первая строка кода). Однако при доступе к "этому" в функции лексической стрелки, которая не вложена в функциональный блок, вы можете получить доступ к глобальному контексту (например, к объекту Window, если ваш код выполняется в браузере).
Надеюсь, это поможет!