Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocha and the this context

So I have this code:

describe('main describe', function() {
    afterEach(function() {
      //this.prop === undefined
    });

    describe('sub', function() {
        it('should do something', function() {
            this.prop = 'test';
        });
    });
});

I don't know why this.prop in the main afterEach is undefined because the follow code work as expected:

describe('main describe', function() {
    afterEach(function() {
      //this.prop === 'test'
    });

    it('should do something', function() {
        this.prop = 'test';
    });
});

Why does the first code not work as I though it would where this.prop should equal 'test' and not undefined?

Is the this keyword tied to only the describe function it is directly contained it?

like image 765
ryanzec Avatar asked Dec 19 '14 23:12

ryanzec


Video Answer


1 Answers

Yep, each describe gets a new Context object. (All the classes I mention can be found in Mocha's source code.) You could get what you are trying to do with:

describe('main describe', function() {
    afterEach(function() {
        console.log(this.prop);
    });

    describe('sub', function() {
        it('should do something', function() {
            this.test.parent.ctx.prop = 'test';
        });
    });
});

The line this.test.parent.ctx.prop is the key. this is the Context associated with the it call. this.test is the Test object associated with the it call. this.test.parent is the Suite object associated with the describe call that immediately contains the it call. this.test.parent.ctx is the context in effect where the describe call appears, which happens to be the same context as this in the afterEach call.

I would actually recommend not traversing Mocha's internal structures and instead doing something like:

describe('main describe', function() {
    var prop;
    afterEach(function() {
        console.log(prop);
    });

    describe('sub', function() {
        it('should do something', function() {
            prop = 'test';
        });
    });
});
like image 98
Louis Avatar answered Oct 13 '22 00:10

Louis