为什么嵌套的describe()块看不到外部块中定义的变量?

Ken*_*ows 46 javascript jasmine

我在实际代码中遇到了这个问题,但我总结了一个简单的例子来证明这一点.

以下代码工作正常.我已经成立了以我的根可变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();
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/w5bzrkh9/

但是,如果我通过执行以下操作尝试稍微干掉我的代码,则会中断:

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();
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/goqcev42/

在嵌套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();
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

And*_*erg 47

这完全符合预期.问题是您的var trees变量orchard在初始化之前尝试访问.描述块的主体在块之前执行beforeEach.要解决此问题,第三个代码段是唯一的方法.

Jasmine将首先执行describe块,然后在运行每个测试之前执行beforeEach块.

  • @Nocomm一般来说,答案是将具有beforeEach()的master describe()中需要共享的beforeEach()的所有描述分组.嵌套没有错误描述在其他描述中! (3认同)