我在实际代码中遇到过这个问题,但我总结了一个简单的例子来证明这一点。
以下代码运行正常。我在我的根describe()
块中设置了一个变量,可以在我的子describe()
s'it()
块中访问。
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
it ('should have apples and oranges', function() {
var trees = orchard.trees;
expect (trees.apple).toBeDefined();
expect (trees.orange).toBeDefined();
expect (trees.apple).toEqual(10);
expect (trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
var trees = orchard.trees;
expect (trees.pear).toBeUndefined();
expect (trees.cherry).toBeUndefined();
});
});
});
但是,如果我尝试通过执行以下操作来稍微干掉我的代码,它会中断:
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
var trees = orchard.trees; // TypeError: Cannot read property 'trees' of undefined
it ('should have apples and oranges', function() {
expect (trees.apple).toBeDefined();
expect (trees.orange).toBeDefined();
expect (trees.apple).toEqual(10);
expect (trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
expect (trees.pear).toBeUndefined();
expect (trees.cherry).toBeUndefined();
});
});
});
在嵌套的describe()
范围内,orchard
对象未定义,即使它在其中的it()
块内定义。
这是Jasmine开发人员的故意,可能是为了避免重置beforeEach()
中的对象并可能破坏某些引用的问题?他们如何实现这一目标?我可以看到这可能有用,我只是很好奇它是如何工作的。 (我的猜测是一些apply()
或call()
魔法,但我不确定如何......)
-
作为旁注,我仍然可以通过简单地使用另一个beforeEach()
块来干掉我的代码:
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
var trees;
beforeEach(function() {
trees = orchard.trees;
});
it ('should have apples and oranges', function() {
expect (trees.apple).toBeDefined();
expect (trees.orange).toBeDefined();
expect (trees.apple).toEqual(10);
expect (trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
expect (trees.pear).toBeUndefined();
expect (trees.cherry).toBeUndefined();
});
});
});
答案 0 :(得分:42)
这完全符合预期。问题是您的var trees
变量在初始化之前尝试访问orchard
。描述块的主体在beforeEach
块之前执行。要解决此问题,第三个代码段是唯一的方法。
Jasmine将首先执行describe块,然后在运行每个测试之前执行beforeEach块。
答案 1 :(得分:1)
那么你仍然可以在beforeEach块之外初始化变量。我通常是为常数做的,并且仍然保持DRY而不引入beforeEach块。
describe('simple object', function () {
const orchard = {
trees: {
apple: 10,
orange: 20
},
bushes: {
boysenberry: 40,
blueberry: 35
}
};
describe('trees', function () {
const trees = orchard.trees;
it('should have apples and oranges', function () {
expect(trees.apple).toBeDefined();
expect(trees.orange).toBeDefined();
expect(trees.apple).toEqual(10);
expect(trees.orange).toEqual(20);
});
it('should NOT have pears or cherries', function () {
var trees = orchard.trees;
expect(trees.pear).toBeUndefined();
expect(trees.cherry).toBeUndefined();
});
});
});
答案 2 :(得分:0)
让我们拿第三个代码片段。此外,它可以重构如下:
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
it ('should have apples and oranges', function() {
expect (orchard.trees.apple).toBeDefined();
expect (orchard.trees.orange).toBeDefined();
expect (orchard.trees.apple).toEqual(10);
expect (orchard.trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
expect (orchard.trees.pear).toBeUndefined();
expect (orchard.trees.cherry).toBeUndefined();
});
});
});
对于 Jasmine 的新人,这就是你如何代表上述代码:\
describe
定义了test suite
。这里的test suite
名称是用户定义的简单字符串,比如“简单对象”。test suite
本身可以包含其他test suites
,这意味着describe
可以包含嵌套套件。orchid
对所有函数都是全局的。在simple object
测试套件中定义的套件。It
阻止称为specification
或SPEC
。 It
块包含单独的测试。Jasmine
执行测试用例时,它将首先访问it
块,这意味着它将遍历所有it
块声明。Jasmine
实际执行测试用例时,它会检查beforeEach
函数,从而orchard
为其分配trees
值。< / LI>
因此您无需在sub suite
内编写beforeEach 函数。你可以忽略
beforeEach(function(){trees = orchard.trees;});
现在将下面的最新代码段与上面的第三个代码段进行比较。