Scope of `this` in jasmine test


#1
describe(xxx, function () {
  beforeAll(function() {
    this.jobCounter = 0;
  })

  it(xxx, function() {
    this.jobCounter++;
    expect(this.jobCounter).toBe(1); // passed
  })

  it(xxx, function() {
    this.jobCounter++;
    expect(this.jobCounter).toBe(2); // failed
  })
})

Can anyone help me understand why the expect() failed for the second it() block?


#2

This is a symptom of how jasmine handles test cases. From Jasmine’s github:

For every test (and their beforeEach/afterEach hooks), jasmine sets the receiver of each function to an initially empty object. This object, which is called userContext within Jasmine’s source code, can have properties assigned to it, and gets blown away at the end of each test. In an attempt to address the issues we were having, we recently switched over to assigning variables to this object, rather than declaring them within describe and then assigning them.

So, the this keyword, which represents the test context, will be reset between test cases. If you want to be able to save the changes made to the global context you can do something along these lines (the “old” way in which jasmine tests were written):

describe('test', function () {
  var jobCounter;
  beforeAll(function() {
    jobCounter = 0;
  });

  it('should equal 1', function() {
    jobCounter++
    expect(jobCounter).toBe(1); // passed
  })

  it('should equal 2', function() {
    jobCounter++;
    expect(jobCounter).toBe(2); // passed
  })
})

Here’s a link to the full post on github for more context: https://gist.github.com/traviskaufman/11131303


#3

@qiwei.li, you should not assume that your it blocks are going to be run sequentially though.
Nothing prevents us from running those it blocks in parallel or in a random order.


#4

how should I write the test if I have sequentially test cases?


#5

You should run them all in your setup and have the it blocks just check one thing.