Проблема в том, что при вызове passObject(myFunction, myObjectInstance);
выполняется немедленно до того, как переменной myObjectInstance
будет присвоено значение.Поэтому, когда код внутри passObject
выполняется, он использует obj
как undefined
для каждого теста, поскольку именно это было передано в то время.
Вместо этого вы можете сделать что-то другое и передать заводская функция для вашей тестовой функции.Это позволит вам обмениваться кодом между основными тестами и тестами в passObject
, в то же время предоставляя гибкость для запуска passObject
с другим объектом.
Вот как будет выглядеть код:
module.exports.passObject = function(fn, createObj) {
describe("inside a function that has a describe block", function() {
beforeAll(function() {
this.obj = createObj();
});
it("and an it block for a class instance", function() {
browser.pause(250);
expect(this.obj).not.toBe(undefined);
expect(this.obj.selector).toBe("object-class-instance");
});
it("and an it block for a function", function() {
browser.pause(250);
expect(fn).not.toBe(undefined);
expect(fn().selector).toBe("object-function");
})
});
}
passObject
теперь принимает функцию, которая создает obj
вместо того, чтобы просто брать obj
.Он также использует контекст this
для передачи этого объекта в тесты.
При использовании этого вам потребуется извлечь инициализацию объекта и повторно использовать его в обоих местах:
function createInstance { return new MyObject(); }
describe("testing passing objects as parameters", function() {
beforeAll(function() {
myObjectInstance = createInstance()
});
it("for a class instance inside describe/it block directly", function() {
browser.pause(250);
expect(myObjectInstance).not.toBe(undefined);
expect(myObjectInstance.selector).toBe("object-class-instance");
});
it("for a function inside describe/it block directly", function() {
browser.pause(250);
expect(myFunction).not.toBe(undefined);
expect(myFunction().selector).toBe("object-function");
});
passObject(myFunction, createInstance);
});
Это приводит к незначительному повторению кода, так как в обоих случаях beforeAll
вызывает функцию, присваивает результат переменной и повторно использует переменную в тестах.Это нормально, поскольку переменная в обоих случаях различна, поэтому разные тесты не должны вызывать ее одно и то же.Однако вы можете устранить даже это повторение, если хотите рискнуть слегка запутать ваш код.
Сначала извлеките весь код beforeAll
в
function setup() {
this.instance = new MyObject();
}
Затем вы можете использовать его в своем beforeAll
напрямую
// in the main tests
beforeAll(setup)
module.exports.passObject = function(fn, setupFn) {
describe("inside a function that has a describe block", function() {
beforeAll(setupFn);
/* ...tests...*/
}
}
Однако, это будет означать, что оба теста должны ссылаться на одно и то же: this.instance
, и не сразу ясно, что должно или должно быть инициализировано в контексте this
для тестов.Кроме того, одному набору тестов может потребоваться больше инициализированных вещей, а другому - меньше, например, один может просто использовать this.instance
, другому может также потребоваться this.foo
.
Так что, если вы выберете этот маршрут, у вас естьконтролировать объем тестов, чтобы функция настройки не увеличивалась и не увеличивалась, чтобы вместить все возможные свойства.
Кроме того, если вы хотите использовать различные имена длято же самое, тогда вы можете просто иметь два свойства, которые указывают на одно и то же значение.Это ослабит некоторые из навязанных стилей для двух наборов тестов.Например:
function setup() {
//for the main tests
this.myObjectInstance = new MyObject();
//for `passObject` just alias the same thing:
this.obj = this.myObjectInstance;
}