Search code examples
node.jsunit-testingsinonsinon-chaiproxyquire

Stubbing Fetch Call - response.json will not invoke


I am trying to stub a fetch call with sinon and sinon-stub-promise. I'm pretty close...but I am not sure why it doesn't invoke the response.json() method I created.

function toJSON(response) {
  console.log(response);       
  return response.json();
}

function init() {
  fetch(darkWeatherUrl)
    .then(toJSON)
    .then(computeHours)
    .then(sendAlerts)
    .catch((e) => {
      console.log('init error ' + e);
    });
}

describe('lifx alert test', ()=> {

  it('should run fetch', ()=> {

    var fetch = sinon.stub().returnsPromise();

    var 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: 0,
              ozone: 296.31 } ]
        }
    };


    function json() {
      return body;
    }

    var response = {};

    response.json = json;


    fetch.resolves(response);
    var init =  proxy('../index.js', {'node-fetch': fetch});
    init();
    fetch.should.have.been.called;
  });

});

 lifex alert test
{ json: [Function: json] }
[ { 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: 0,
    ozone: 296.31 } ]
init error TypeError: response.json is not a function
    â should run fetch


  1 passing 

Solution

  • See update on the bottom also

    I removed sinon-stub-promise and kept it native sinon:

    describe('lifx alert test', ()=> {
      var fetchStub;
    
      beforeEach(() => {
        fetchStub = sinon.stub();
      });
    
      it('should run fetch', ()=> {
    
        var 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: 0,
                  ozone: 296.31 } ]
            }
        };
    
    
        var response = { json: () => { return body } };
        fetchStub.returns(Promise.resolve(response));
        var init =  proxy('../index.js', {'node-fetch': fetchStub});
        init();
        fetchStub.should.have.been.called;
      });
    

    UPDATE

    I got it to work with sinon-stub-promise with proxyquire's global attribute:

    describe('lifx alert test', ()=> {
    
      it('should run fetch', ()=> {
    
        var fetch = sinon.stub().returnsPromise();
    
        var 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 } ]
            }
        };
    
    
        var response = { json: () => { return body } };
    
    
        fetch['@global'] = true;
        fetch.resolves(response);
        proxy('../index.js', {'node-fetch': fetch});
        fetch.should.have.callCount(3);
      });
    
    });