Supertest fails to test repeated post request

I'm testing an api that creates users. The api does not allow the creation of users with the same login value. So I wrote the tests below:

const app = require('../config/express'); //exports a configured express app
const request = require('supertest');
const {populateUsers} = require('../seeders/users.seed');

beforeEach(populateUsers);//drop and populate database with some seeders

describe('POST /v1/users', () => {
  it('#Post a new user - 201 status code', (done) => {
    request(app)
        .post('/v1/users')
        .send({
                login:'user-teste-01',
                password: 'pass01'
        }).expect(201, done);           
  });
  it('#Post repeated login - 400 status code', (done) => {
    request(app)
        .post('/v1/users')
        .send({
                login:'user-teste-01',
                password: 'pass01'
        }).expect(400, done);
  });
});

The firts test works, but the second test returns the following error:

Error: expected 400 "Bad Request", got 201 "Created"

I did the tests manually and the api works correctly (returning 400 status code).

Where did I make the mistake in this test?

Upvotes: 1

Views: 3054

Answers (2)

deerawan
deerawan

Reputation: 8443

it is because you have beforeEach that reset your database. This hook will be executed in every test so in your 400 status code, you no longer have user user-teste-01 because it has been reset by beforeEach.

There are some solutions for this:

#1 Use login and password that exist in your seed

it('#Post repeated login - 400 status code', (done) => {
  request(app)
    .post('/v1/users')
    .send({
      login: 'user-exist-in-seed',
      password: 'pass01'
    }).expect(400, done);
});

#2 Create a user again before running the scenario

context('when user is already exist', function() {
  beforeEach(function() {
    // create a user `user-teste-01`
    // use beforeEach so it will be executed after seeding
  })

  it('#Post repeated login - 400 status code', (done) => {
    request(app)
      .post('/v1/users')
      .send({
        login: 'user-teste-01',
        password: 'pass01'
      }).expect(400, done);
  });
});

3 Use before instead of beforeEach for seeding

It will run once before all tests

before(populateUsers);//drop and populate database with some seeders

Upvotes: 2

Aaron
Aaron

Reputation: 1306

So it looks like your beforeEach is being called before each individual test. So your table is being reset/reseeded after you add the first user. Maybe try putting your populate users in a before() instead, that way it happens only once. I'm not 100% certain, but let me know if that works for you.

I would be very surprised if this doesn't do what you expect it to if, for example, you removed the beforeEach() altogether.

Upvotes: 1

Related Questions