Search code examples
node.jsmongoosemocha.jschaichai-http

API unit test using chai giving wrong result


I am writing unit test for my API which uses nodejs and mongoose. I am using mocha, chai, and chai-http to do unit testing.

I am testing a POST request that creates a customer. The first test creates a customer, and it passes. The last test will try to create a customer but should fail since the email already exist, but that fails since the request creates a new customer.

I tried doing the requests manually using postman and it gives the right behaviour.

Here are the tests:

describe('Customer', () => {

//Before each test we empty the database
beforeEach((done) => {
    Customer.remove({}, (err) => {
        done();
    });
});

// Creating Customer test
describe('POST Account - Creating customer account', () => {

    it('creating a user with correct arguments', (done) => {

        // defining the body
        var body = {
            first_name : "Abdulrahman",
            last_name : "Alfayad",
            email: "[email protected]",
            password: "123"
        };

        chai.request(server)
        .post('/api/customer/account')
        .send(body).end((err, res) => {
            res.body.should.have.property('status').and.is.equal('success');
            res.body.should.have.property('message').and.is.equal('customer was created');
            done();
        });
    });

    it('creating a user with incorrect arguments', (done) => {

        // defining the body
        var body = {
            first_name: "Abdulrahman",
            email: "[email protected]",
        };

        chai.request(server)
            .post('/api/customer/account')
            .send(body).end((err, res) => {
                res.body.should.have.property('status').and.is.equal('failure');
                res.body.should.have.property('message').and.is.equal('no arguments were passed');
                done();
            });
    });

    it('creating a user with an already existing email in the DB', (done) => {

        // defining the body
        var body = {
            first_name: "Abdulrahman",
            last_name: "Alfayad",
            email: "[email protected]",
            password: "123"
        };

        chai.request(server)
            .post('/api/customer/account')
            .send(body).end((err, res) => {
                res.body.should.have.property('status').and.is.equal('failure');
                res.body.should.have.property('message').and.is.equal('email already exist');
                done();
            });
    });

});

});


Solution

  • I feel that this is because you use beforeEach to empty the customer database. beforeEach hook will be executed before each test so when you were running the email scenario test, your database actually was empty.

    The easiest way to solve it is to create a new customer again before the existing email scenario such as:

    it('creating a user with an already existing email in the DB', (done) => {
    
      // NOTE: Create a user with email "[email protected]"
    
      // defining the body
      var body = {
        first_name: "Abdulrahman",
        last_name: "Alfayad",
        email: "[email protected]",
        password: "123"
      };
    
      chai.request(server)
        .post('/api/customer/account')
        .send(body).end((err, res) => {
          res.body.should.have.property('status').and.is.equal('failure');
          res.body.should.have.property('message').and.is.equal('email already exist');
          done();
        });
    });
    

    Hope it works