Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test in loop mocha

I am trying to use data provider in mocha to write less code

var should = require('should'); 
var assert = require('assert');
var request = require('supertest');  
var mongoose = require('mongoose');
var winston = require('winston');
var config = require('../app/config');

describe('Authentification', function() {
    var url = config.web.protocol + '://' + config.web.host + ':' + config.web.port;

    describe('signin',function()
    {
        var provider = [
            {
                describe: 'should return error trying to signin with empty body',
                body: {},
                status: 404,
                message: "firstName not found"
            },
            {
                describe: 'should return error trying to signin with no first name',
                body: {
                    lastName: 'test',
                    password: 'test',
                    email: 'test'
                },
                status: 404,
                message: "firstName not found"
            },
            {
                describe: 'should return error trying to signin with no last name',
                body: {
                    firtsName: 'test',
                    password: 'test',
                    email: 'test'
                },
                status: 404,
                message: "lastName not found"
            },
            {
                describe: 'should return error trying so signin with no password',
                body: {
                    lastName: 'test',
                    firstName: 'test',
                    email: 'test'
                },
                status: 404,
                message: "password not found"
            },
            {
                describe: 'should return error trying so signin with no email',
                body: {
                    lastName: 'test',
                    password: 'test',
                    firstName: 'test'
                },
                status: 404,
                message: "email not found"
            },
            {
                describe: 'should return error trying so signin a too long firstName',
                body: {
                    firstName: 'kldsfjghsldkglsqkdjghqlkfjdsghldfksjghfdlskjgkldjfsdj',
                    lastName: 'test',
                    password: 'testhdksjdhfb',
                    email: '[email protected]'
                },
                status: 400,
                message: "invalid firstName"
            },
        ];

        for (var i in provider) {
            it(provider[i].describe, function(done) {
            request(url)
                .post('/user/signin')
                .send(provider[i].body)
                .expect(provider[i].status)
                .expect(function(res)
                {
                    assert.equal(res.body.code, provider[i].status);
                    assert.equal(res.body.message, provider[i].message);
                })
                .end(done);
            });
        }
    });
});

But in this case it only check the last test.

The output is

  Authentification
    signin
      ✓ should return error trying to signin with empty body 
      ✓ should return error trying to signin with no first name 
      ✓ should return error trying to signin with no last name 
      ✓ should return error trying so signin with no password 
      ✓ should return error trying so signin with no email 
      ✓ should return error trying so signin a too long firstName 


  6 passing (71ms)

But if the last test fail, all others test fail. and if one of the other test is wrong, the test pass.

There is maybe an asynchronious problem, but I don't know how to solve it

like image 738
Ajouve Avatar asked Feb 21 '15 16:02

Ajouve


People also ask

Does Mocha run tests in parallel?

Mocha does not run individual tests in parallel. That means if you hand Mocha a single, lonely test file, it will spawn a single worker process, and that worker process will run the file. If you only have one test file, you'll be penalized for using parallel mode.

Does Mocha run tests in order?

Mocha will run the tests in the order the describe calls execute.


1 Answers

Change your for loop to something like this:

function makeTest(p) {
    it(p.describe, function(done) {
        request(url)
            .post('/user/signin')
            .send(p.body)
            .expect(p.status)
            .expect(function(res) {
                assert.equal(res.body.code, p.status);
                assert.equal(res.body.message, p.message);
            })
            .end(done);
    });
}

for (var i in provider) {
    makeTest(provider[i]);
}

The problem with the code you have is that you are actually only testing the last element in your array. (Yes, even though you see different test names.) The anonymous function you pass to it will execute at some point in the future, when Mocha gets to it. By that time your loop will have finished executing and the value of i will be the last value that the loop gave to it. It is not a problem for the first argument you give to it because that argument is evaluated right away. This is why the test names are okay but the tests themselves are just multiple instances of testing the last element in your array.

The code above solves the issue by passing provider[i] to makeTest. When the anonymous function in makeTest then refers to the p that was used when it was created, it has the value that was used when makeTest was called.

like image 159
Louis Avatar answered Sep 19 '22 12:09

Louis