node.jsunit-testingmocha.js

Using Mocha to run unit test for Node.js not working as expected


I am using mocha to run a unit test on my Node.js server code which inserts a user address, reads it and validates data and then deletes the address.

it('Create User Address', function(done) {
    var userId = 'testID';
    var address = '123 Test Cres';
    var city = 'Toronto';
    var region = 'Ontario';
    var country = 'Canada';
    var startDate = new Date().getTime() / 1000;
    var responseWrite = {};
    var responseRead = {};
    request('http://127.0.0.1:5003/cloud-medic/us-central1/app/createUserProfile' + '?userId=' + userId + '&address='
            + address + '&city=' + city + '&region=' + region + '&country=' + country + '&startDate=' + startDate, async function(error, response, body) {
        console.log("Getting response after write");
        responseWrite = await JSON.parse(body);
        console.log(responseWrite);
        expect(responseWrite.userProfile.userId).to.equal(userId);

        request('http://127.0.0.1:5003/cloud-medic/us-central1/app/getUserProfile' + '?id=' + responseWrite.userProfile.id, async function(error, response, body) {
                console.log("Getting response id after write!!!!!!!!!!!!!!!!!!!!!!!!");
                console.log(responseWrite);
                responseRead = await JSON.parse(body);
                console.log("Getting response id after READ!!!!!!!!!!!!!!!!!!!!!!!!");
                console.log(responseRead.userProfile);
                expect(responseRead.userProfile.userId).to.equal(userId);
                expect(responseRead.address).to.equal(address);
                expect(responseRead.city).to.equal(city);
                expect(responseRead.region).to.equal(region);
                expect(responseRead.country).to.equal(country);
                //console.log(responseRead.startDate);

            });
         done();
    });


    // tear down delete user profile created for test
    after(function () {
        request.delete({url:'http://127.0.0.1:5003/cloud-medic/us-central1/app/deleteUserProfile',
                 form: {id: responseWrite.userProfile.id}}, async function(err,httpResponse,body){
                 console.log("DELETEING PROFILE" + responseWrite.userProfile.id);
                 console.log(body);
                 responseDelete = await JSON.parse(body);
                 expect(responseDelete.userProfileStatus).to.equal(200);
                 //done();

         });
      });


});

This code works however it doesn't seem to execute the expect assertations on the profile address (userId, address, city, region, country). So if I change the userId to "THROW ERROR" it throws an unexpected error.

expect(responseWrite.userProfile.userId).to.equal("THROW ERROR");

The error is based on a timeout which is thrown when I ran the unit tests:

 1) Create User Address:
     Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/Users/Projects/CloudMedic/test/test-user.js)

I run the tests using at 10000ms timeout. npm test Any idea on what is causing this weird behaviour? Thanks for your help.


Solution

  • I moved away from the callback using done. Instead of using the request library I am now using the node.js fetch command and promises. Here is the code that now works for me:

    it('Create User Address', async function() {
        var userId = 'zcU7Q09GwsdvtKrLaR8M';
        var address = '123 Test';
        var city = 'Toronto';
        var region = 'Ontario';
        var country = 'Canada';
        var startDate = new Date().getTime();
        var responseWrite = {};
        var responseRead = {};
        await fetch('http://127.0.0.1:5003/cloud-medic/us-central1/app/createUserProfile' + '?userId=' + userId + '&address='
                + address + '&city=' + city + '&region=' + region + '&country=' + country + '&startDate=' + startDate, {
                method: "GET"
                }).then(response => response.json())
                   .then(async response => {
                    console.log("Getting response after write");
                    responseWrite = response;
                    console.log(responseWrite.userProfile.id);
                    expect(responseWrite.userProfile.userId).to.equal(userId);
    
                    await fetch('http://127.0.0.1:5003/cloud-medic/us-central1/app/getUserProfile' + '?id=' + responseWrite.userProfile.id, {
                            method: "GET"
                            }).then(response => response.json())
                               .then(response => {
                                responseRead = response;
                                console.log("Getting response id after READ!!!!!!!!!!!!!!!!!!!!!!!!");
                                console.log(responseRead.userProfile);
                                expect(responseRead.userProfile.userId).to.equal(userId);
                                expect(responseRead.userProfile.address).to.equal(address);
                                expect(responseRead.userProfile.city).to.equal(city);
                                expect(responseRead.userProfile.region).to.equal(region);
                                expect(responseRead.userProfile.country).to.equal(country);
                                expect(responseRead.userProfile.startDate._seconds).to.equal(Math.trunc(startDate/1000));
                        });
                });
    
        // tear down delete user profile created for test
       after(async function () {
            await fetch('http://127.0.0.1:5003/cloud-medic/us-central1/app/deleteUserProfile',
                    { method: 'DELETE',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ id: responseWrite.userProfile.id})
                 }).then(response => response.json())
                   .then(response => {
                     responseDelete = response;
                     expect(responseDelete.userProfileStatus).to.equal(200);
    
                });
          });