Test in loop mocha

强颜欢笑 提交于 2020-01-21 11:09:24

问题


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: 'test@aa.aa'
                },
                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


回答1:


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.



来源:https://stackoverflow.com/questions/28648022/test-in-loop-mocha

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!