Is it a good idea to save these common assertions in a seprate file and not repeat it?

Viewed 76

Is it a good idea to save these common assertions in a separate file and not repeat it? I wrote in this way since it is a bdd format. If yes, how can i do it

var expect  = require('chai').expect;
var request = require('request');
var chai = require('chai')
  , chaiHttp = require('chai-http');

chai.use(chaiHttp);
var should = chai.should();


describe('Employees', function() {
    var url = 'http://localhost:3000';

    it('Returns Employees', function(done) { // <= Pass in done callback
       chai.request(url)
       .get('/employees')
       .end(function(err, res) {
       expect(res).to.have.status(200);
       res.should.be.json;
       res.body.forEach((item) => {
       item.should.have.property("first_name");
       item.should.have.property("last_name");
       item.should.have.property("email");
       item.should.have.property("id");
       })
       done(); });
});

    it('Add an Employee', function(done) { // <= Pass in done callback
       chai.request(url)
       .post('/employees')
       .send({"first_name": "asdad", "last_name": "asdasd", "email": "asdasd@example.com"})
       .end(function(err, res) {
       expect(res).to.have.status(201);
       res.should.be.json;
       res.body.should.have.property("first_name");
       res.body.should.have.property("last_name");
       res.body.should.have.property("email");
       global.idVariable = res.body.id;
       done(); });
});

it seems like below are just being repeative:

expect(res).to.have.status(200);
           res.should.be.json;
           res.body.forEach((item) => {
           item.should.have.property("first_name");
           item.should.have.property("last_name");
           item.should.have.property("email");
           item.should.have.property("id");
           })
1 Answers

Maybe you could just wrap these common Employee related assertions into a function? Then call this EmployeeAssertion function on a per test basis for each test that needs to assert the Employee response to verify common employee attributes. I don't know that it makes sense to separate this assertion check into another file unless your employee assertion check function is needed in multiple test files. The main thing to remember is that: each of your individual unit tests should test one thing, and should be isolated from each other. There is no harm in creating a shared assertion function in order to implement the (DRY) don't repeat yourself principle as long as this function contains only the bare minimum of the commonalities across each employee related test and state is not remembered across each test in order to ensure isolation across tests.

For example, something along the following:

var expect  = require('chai').expect;
var request = require('request');
var chai = require('chai')
  , chaiHttp = require('chai-http');

chai.use(chaiHttp);
var should = chai.should();

const assertEmployeeAttrs = (res) => {
    res.should.be.json;
    res.body.forEach((item) => {
      // common employee attributes 
      item.should.have.property("first_name");
      item.should.have.property("last_name");
      item.should.have.property("email");
    })
};


describe('Employees', function() {
    var url = 'http://localhost:3000';

    it('Returns Employees', function(done) { // <= Pass in done callback
       chai.request(url)
       .get('/employees')
       .end(function(err, res) {
       // unique assertions per test i.e. res status codes, etc...
       expect(res).to.have.status(200);
       // common assertions across each employee test. i.e. base employee attributes
       assertEmployeeAttrs(res);
       done(); });
});

    it('Add an Employee', function(done) { // <= Pass in done callback
       chai.request(url)
       .post('/employees')
       .send({"first_name": "asdad", "last_name": "asdasd", "email": "asdasd@example.com"})
       .end(function(err, res) {
       // unique attributes 
       expect(res).to.have.status(201);
       // common employee attributes  
       assertEmployeeAttrs(res);
       global.idVariable = res.body.id;
       done(); });
});

In response to your additional question of: How to add this Employee assertion check into a separate file and call it from another file?

The approach is the following:

  1. Add this Employee assertion code check code into another file.
  2. Export this newly added functionality with module.exports.
  3. require this new code into any file that needs to use this Employee Assertion check and use same as before.

In code this looks like the following:

employeeAssert.js (new file)

var expect  = require('chai').expect;
var request = require('request');
var chai = require('chai');
var chaiHttp = require('chai-http');

chai.use(chaiHttp);
var should = chai.should()

let employeeAssert = {};

employeeAssert.hasAttrs = (res) => {
   res.should.be.json;
   res.body.forEach((item) => {
      // common employee attributes 
      item.should.have.property("first_name");
      item.should.have.property("last_name");
      item.should.have.property("email");
   })
};

module.exports = employeeAssert;

File using Employee Assertion check:

var expect  = require('chai').expect;
var request = require('request');
var chai = require('chai');
var chaiHttp = require('chai-http');
// change path as appropriate, for now we assume the same parent dir
var employeeAssert = require('./employeeAssert);

chai.use(chaiHttp);
var should = chai.should();

describe('Employees', function() {
var url = 'http://localhost:3000';

it('Returns Employees', function(done) { // <= Pass in done callback
     chai.request(url)
     .get('/employees')
     .end(function(err, res) {
        expect(res).to.have.status(200);
        employeeAssert.hasAttrs(res);
        done(); 
     });
 });    
Related