问题
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