Search code examples
javascriptnode.jsnocknode.js-got

Testing basic async http request in Node with Got, Nock & Chai


I am trying to figure out why my unit test is not working correctly. It seems that the external network request is made despite my using Nock to intercept my http request.

I have a very basic getUser service, getuser-got.js:

    const got = require('got');
    
    module.exports = {
      getUser(user) {
        return got(`https://api.github.com/users/${user}`)
        .then(response=>JSON.parse(response.body))
        .catch(error => console.log(error.response.body))
      }
    };

This can be called succesfully but I want a unit test for it.

Here's my code in a file named getuser-got.test.js:

    const getUser = require('../getuser-got').getUser;
    
    const expect = require('chai').expect;
    const nock = require('nock');
    
    const user_response = require('./response');
    
    describe('GetUser-Got', () => {
      beforeEach(() => {
        nock('https//api.github.com')
        .get('/users/octocat')
        .reply(200, user_response);
      });
      it('Get a user by username', () => {
        return getUser('octocat')
          .then(user_response => {
            // expect an object back
            expect(typeof user_response).to.equal('object');
            // test result of name and location for the response
            expect(user_response.name).to.equal('The Octocat')
            expect(user_response.location).to.equal('San Francisco')
          })
      });
    });

The file named response contains a copy of the expected response from the Github API, which I am loading into the user_response variable. I have replaced the values for name and location in order to make my test fail.

    module.exports = {
        login: 'octocat',
    ...
        name: 'The FooBar',
        company: '@github',
        blog: 'https://github.blog',
        location: 'Ssjcbsjdhv',
    ...
    }

The problem is that I can see that Nock is not intercepting my request. When I run the test it continues to make an actual call to the external API. The test therefore passes, because it is not using my local response as the return value.

I've tried adding in nock.disableNetConnect(); but this just causes the test to timeout, as it's clearly still trying to make the external call. If I run my test I get:

➜  nock-tests npm test

> [email protected] test /Users/corin/Projects/nock-tests
> mocha "test/test-getuser-got.js"



  GetUser-Got
    ✓ Get a user by username (290ms)


  1 passing (296ms)

What am I doing wrong to not have Nock intercept my http request?


Solution

  • The value being passed to the nock function is not a valid URL, it's missing the colon in the schema.

    Updating it to nock('https://api.github.com') gets the test to fail locally, as desired.