MochaJS and Chai test dynamic ID

Viewed 619

I am trying to generate some assertions to test my Restful CRUD API but I am not how to test new generated documents. I am using Express + Firebase also, so I was able to test easily users since the ID is the email itself. But in the case of any other documents the IDs are being created randomly.

For example, my user test looks like this:

    describe('POST - /api/admin/users', () => {
        it('Should create a user', done => {
            const user: IUser = {
                name: 'User TDD Test',
                email: 'tdd@test.com',
                password: '123456',
                createdAt: 1585848131576
            };

            chai.request(server)
                .post('/api/admin/users')
                .send(user)
                .end((err, response) => {
                    response.should.have.status(201);
                    response.body.should.be.an.instanceOf(Object);
                    response.body.should.have.property('message').eq('User created');
                    response.body.should.have.property('data')
                        .and.be.an.instanceOf(Object)
                        .and.have.property('name').eq('UserTDD Test');
                    response.body.should.have.property('ok').eq(true);
                    done();
                });
        });
    });

    describe('PUT - /api/admin/users/:email', () => {
        it('Should update a user', done => {
            const email = 'tdd@test.com'
            const user: object = {
                password: '1234567',
                updatedAt: 1585848131576
            };

            chai.request(server)
                .put('/api/admin/users/' + email)
                .send(user)
                .end((err, response) => {
                    response.should.have.status(201);
                    response.body.should.be.an.instanceOf(Object);
                    response.body.should.have.property('message').eq('User updated');
                    response.body.should.have.property('data').eq(null);
                    response.body.should.have.property('ok').eq(true);
                    done();
                });
        });
    });

Here it's easy to update the same document since they share the same email. But, for example, if I want to update any other collection with a generated ID I won't able to test creation and updates the same way, right?

For example, if I have the same code for a collection "tickets":

describe('POST - /api/admin/tickets', () => {
        it('Should create a ticket', done => {
            const ticket: ITicket = {
                owner: 'tdd@test.com',
                status: 'Open',
                createdAt: 1585848131576
            };

            chai.request(server)
                .post('/api/admin/tickets')
                .send(ticket)
                .end((err, response) => {
                    response.should.have.status(201);
                    response.body.should.be.an.instanceOf(Object);
                    response.body.should.have.property('message').eq('Created ticket');
                    response.body.should.have.property('data')
                        .and.be.an.instanceOf(Object)
                        .and.have.property('owner').eq('tdd@test.com');
                    response.body.should.have.property('ok').eq(true);
                    done();
                });
        });
   });

Then, the previous generated ticket has an ID property with an unknown value, so, should I test "PUT method" for a different ticket with a known ID?

1 Answers

I know this is not a solution but a workaround. I think this is not even a good practice, but it works.

First I added NODE_ENV=test to the environment variables when testing:

"scripts": {
    "dev": "ts-node-dev src/app.ts",
    "start": "node dist/app.js",
    "test": "env NODE_ENV=test TS_NODE_PROJECT=\"tsconfig.testing.json\" mocha --require ts-node/register 'src/test/**/*.ts'",
    "build": "tsc -p"
  },

I just added the ID to the req.body and only read it if process.env.NODE_ENV === 'test'. So I added this to the route:

    const data: object = req.body;
    ...
    const id: string = !empty(data.id) && process.env.NODE_ENV === 'test' ? data.id : null;
    delete data.id;

    const ref: any = !empty(id)
        ? db.collection('tickets').doc(id) 
        : db.collection('tickets');

    try {

        empty(id) ? await ref.add(data) : await ref.set(data);
        result.message = 'Ticket created';
        result.data = data;
        result.ok = true;
        return res.status(201).json(result);
    } catch(error) {
        result.message = 'Couldn\'t create ticket';
        result.error = error;
        console.log(error);
        return res.status(500).json(result);
    }
Related