0

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?

1 Answer 1

1

I saw that we mix between async/await and promise which is not unnecessary. This probably the culprit of the bug.

helper can be improved as

async function clean_db() {
  const client = new Client(dbConfig);

  try { // using try catch to catch error
    await client.connect(); // specify await, take a look at its doc 

    await client.query( 
      `TRUNCATE TABLE "templates"; 
       ALTER SEQUENCE "templates_id_seq" RESTART WITH 1;`
      )

     await client.end(); // specify await
  } catch (err) {
    console.error(err);
  };
}

Notice that there's no more promise (then) and we use async/await solely.

insertTemplate could be improved as

async function insertTemplate(myTemplate) {
  const client = new Client(dbConfig);
  const { name, status, version } = myTemplate;

  try {
    await client.connect();

    await client.query(
      SQL`INSERT INTO templates (name, status, version )
      VALUES (${name}, ${status}, ${version})
      RETURNING id`)

      await client.end();
  } catch (err) {
    console.error(err)
  }
}

Reference: https://node-postgres.com/

Sign up to request clarification or add additional context in comments.

2 Comments

I take it that there's an async missing from the clean_db() function?
@Dycey yes, I forgot to put that async there. I updated the code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.