Tuesday, 9 May 2017

Memory reference issue in Mocha - modified object shows unmodified

Using Node, Sinon, Nock, and Mocha.

I am having a scope issue it seems.

In the describe('When rain is in the forcast') block everything runs fine. I am able to modify the body object, such as body.hourly.data[3].precipIntensity = .099; inside it('should send a normal alert for heavy rain' and the nock uses the modified body object.

However, in the describe('When dangerous weather is in forcast'), when I modify the same body object, nock uses the body as if I did not modify it. Such as body.hourly.data[3].icon = 'hail'; in it('should send danger alert for hail')...the console.log in the function checkBadConditions() shows clear-day when it should show hail.

I am confused on the memory reference behavior/issue.

source code:

function checkBadConditions(hourData) {
  console.log(hourData.icon)
  if (hourData.icon === 'hail' || hourData.icon === 'thunderstorm'
      || hourData.icon === 'tornado') {
        return true;
      } else {
        return false;
      }
}


describe('When weather is bad', ()=> {
  var dangerAlert;
  var normalAlert;
  var body;
  var sandbox;
  var index;

  before((done)=> {
    body = {
      "hourly": {
         data:
           [ { time: 1493413200,
              icon: 'clear-day',
              precipIntensity: 0,
              precipProbability: 0,
              ozone: 297.17 },
            { time: 1493416800,
              icon: 'clear-day',
              precipIntensity: 0,
              precipProbability: 0,
              ozone: 296.89 },
            { time: 1493420400,
              icon: 'clear-day',
              precipIntensity: 0,
              precipProbability: 0,
              ozone: 296.73 },
            { time: 1493424000,
              icon: 'clear-day',
              precipIntensity: 0,
              precipProbability: 50,
              ozone: 296.31 } ]
        }
    };

    sandbox = sinon.sandbox.create();
    dangerAlert = sandbox.stub(require('../alerts'), 'dangerAlert');
    normalAlert = sandbox.stub(require('../alerts'), 'normalAlert');
    index = require('../index');

    done();
  });

  afterEach(()=> {
    sandbox.reset();
  });

  describe('When rain is in the forecast', ()=> {

    it('should send a normal alert for light rain', ()=> {
      nock('https://api.darksky.net')
        .get(/.*/)
        .reply(200, body);

      return index.init().then(()=> {
        normalAlert.should.to.be.calledTwice;
        normalAlert.should.be.calledWith('light');
      });
    });

    it('should send a normal alert for heavy rain', ()=> {
      body.hourly.data[3].precipIntensity = .099;

      nock('https://api.darksky.net')
        .get(/.*/)
        .reply(200, body);

      return index.init().then(()=> {
        normalAlert.should.to.be.calledTwice;
        normalAlert.should.be.calledWith('heavy');
      });
    });

    it('should not send a second alert', ()=> {
      var alerts = require('../alerts');
      alerts.lock.normalAlert = true;

      nock('https://api.darksky.net')
        .get(/.*/)
        .reply(200, body);

      return index.init().then(()=> {
        normalAlert.should.not.be.calledTwice;
      });
    });
  });

  describe('When dangerous weather is in forcast', ()=> {

    // HERE IS WHERE THE MODIFIED BODY BEHAVIOR ISSUE STARTS

    it('should send danger alert for hail', ()=> {
      body.hourly.data[3].icon = 'hail';
      nock('https://api.darksky.net')
        .get(/.*/)
        .reply(200, body);

      return index.init().then(()=> {
        dangerAlert.should.to.be.calledTwice;
        normalAlert.should.not.be.called;
      });
    });

    it('should send danger alert for thunderstorm', ()=> {
      body.hourly.data[3].icon = 'thunderstorm';
      nock('https://api.darksky.net')
        .get(/.*/)
        .reply(200, body);

      return index.init().then(()=> {
        dangerAlert.should.to.be.calledTwice;
      });
    });


results:

  When weather is bad
    When rain is in the forcast
clear-day
clear-day
clear-day
clear-day
      â should send a normal alert for light rain
clear-day
clear-day
clear-day
clear-day
      â should send a normal alert for heavy rain
clear-day
      â should not send a second alert
    When dangerous weather is in forcast
clear-day
      1) should send danger alert for hail
clear-day
      2) should send danger alert for thunderstorm
clear-day
      3) should send danger alert for tornado
clear-day
      4) should send a danger alert after normal alert


  11 passing (166ms)
  4 failing

  1) When weather is bad When dangerous weather is in forcast should send danger alert for hail:
     AssertionError: expected dangerAlert to have been called exactly twice, but it was called 0 times
      at index.init.then (test/index.js:97:33)
      at process._tickCallback (internal/process/next_tick.js:103:7)

  2) When weather is bad When dangerous weather is in forcast should send danger alert for thunderstorm:
     AssertionError: expected dangerAlert to have been called exactly twice, but it was called 0 times
      at index.init.then (test/index.js:109:33)
      at process._tickCallback (internal/process/next_tick.js:103:7)

  3) When weather is bad When dangerous weather is in forcast should send danger alert for tornado:
     AssertionError: expected dangerAlert to have been called exactly twice, but it was called 0 times
      at index.init.then (test/index.js:120:33)
      at process._tickCallback (internal/process/next_tick.js:103:7)

  4) When weather is bad When dangerous weather is in forcast should send a danger alert after normal alert:
     AssertionError: expected normalAlert to have been called exactly twice, but it was called 0 times
      at index.init.then (test/index.js:134:30)
      at process._tickCallback (internal/process/next_tick.js:103:7)



via dman

No comments:

Post a Comment