jeudi 24 octobre 2019

Testing DB Inserts in Javascript with async/await using jest & supertest

I'm trying to write tests for a React/Postgres stack, and guess what ? It works ... sometimes :-(

I'm using a helper file to reset the database between tests:

// partial contents of dbtools.js
function clean_db(){
  const client = new Client(dbConfig);
  client.connect();
  client.query( 
    `TRUNCATE TABLE "templates"; 
     ALTER SEQUENCE "templates_id_seq" RESTART WITH 1;`
    )
    .catch( err => { console.error(err); } )
    .then( () => client.end() );
}

The tests themselves are roughly:

const request = require('supertest');
const app = require('../app');
const { Client } = require('pg');
const SQL = require('sql-template-strings');
const dbConfig = require('../db');
const { clean_db } = require('./helpers/dbtool');
const faker = require('faker');

async function insertTemplate(myTemplate) {
  const client = new Client(dbConfig);
  const { name, status, version } = myTemplate;
  client.connect();
  await client.query(
    SQL`INSERT INTO templates (name, status, version )
    VALUES (${name}, ${status}, ${version})
    RETURNING id`)
    .catch( err => console.error(err) )
    .then( () => client.end() );
}

function randomTemplate() {
  return {
    name: faker.internet.userName,
    status: 'new',
    version: String(faker.random.number())
  };
}


beforeAll(async () => {
  await clean_db();
});

afterAll(async () => {
  await clean_db();
});

describe('GET /templates', () => {

  //... other tests ...

  describe('When there are 1 or more records in the table', () => {

    const templ1 = randomTemplate();
    const templ2 = randomTemplate();
    const templ3 = randomTemplate();

    beforeEach(async () => {
      await clean_db();
      const t1_added = await insertTemplate(templ1);
      const t2_added = await insertTemplate(templ2);
      const t3_added = await insertTemplate(templ3);
    });

    afterEach(async () => {
      await clean_db();
    });

    // here's one example problem child
    test('It should respond with an JSON array of records', async done => {
      const response = await request(app).get('/templates');
      expect(response.body.length).toBe(3);
      console.error(response.body);
      done();
    });

    //... more tests ...

    });
  });
});

My suspicion is that the inserts aren't being completed before the test runs.

The error I get back is something along the lines of:

 FAIL  tests/templates.test.js
  ● GET /templates › When there are 1 or more records in the table › It should respond with an JSON a
rray of records

    expect(received).toBe(expected) // Object.is equality

    Expected: 3
    Received: 2

      94 |     test('It should respond with an JSON array of records', async done => {
      95 |       const response = await request(app).get('/templates');
    > 96 |       expect(response.body.length).toBe(3);
         |                                    ^
      97 |       console.error(response.body);
      98 |       done();
      99 |     });

      at Object.toBe (tests/templates.test.js:96:36)

Is there something I'm doing wrong with the async/await? Is the strategy just wrong?

Aucun commentaire:

Enregistrer un commentaire