来自 beforeEach 运行 的代码在 'it'spec 之后

Code from beforeEach running after the 'it'spec

我正在使用 mocha 和 supertest 来测试 REST 服务。在这种情况下,我需要测试 GET 请求后的后续登录 returns 来自该 GET 请求的查询。

  1. 登录用户
  2. 使用参数在端点上执行 GET 请求
  3. 登录用户并期望来自 GET 请求的参数作为响应。

由于上面的测试将针对不同的端点执行多次,这就是我想出的:

/*
 * getRequest.js
 */
'use strict';

var request = require('supertest')
    , verifyUrl = require('./verifyUrl') // verifies basic url formatting
    ;

module.exports = getRequest;

/**
 * Perform GET request using given parameters and call next when finished.
 * @param getEnvironment {json}
 * @param getEnvironment.url {string}
 * @param getEnvironment.endPoint {string}
 * @param getEnvironment.authorization {string}
 * @param next {function} The callback
 */
function(getEnvironment, getParams, next) {
    var url = verifyUrl(getEnvironment.url);
    request(url)
        .get(getEnvironment.endPoint)
        .set("authorization", getEnvironment.authorization)
        .set('Accept', 'application/json')
        .query(getParams)
        .end(next)
}

/*
 * loginWithCallback.js
 * 
 * Performs a basic login but depends on the callback to test the results of the login.
 */
'use strict';

var request = require('supertest')
    , VerifyUrl = require('./VerifyUrl')
    ;

module.exports = LoginWithCallback;

/**
 * Perform basic login, then call next passing in err and res for testing.
 *
 * @param setEnvironment {json}  Expects url and authorization. Any other parameters will be ignored.
 * @param setEnvironment.url {string} The url being tested.
 * @param setEnvironment.authorization {string} 
 * @param next {function} callback function that will perform the actual test.
 */
function LoginWithCallback(setEnvironment, next) {

    var url = VerifyUrl(setEnvironment.url);

    request(url)
        .post('api/users/login')
        .set('authorization', setEnvironment.authorization)
        .set('Accept', 'application/json')
        .end(next);
}

/*
 * e2eTest.js
 */
'use strict';

var base64_encode = require('Base64').btoa
    , should = require('should')
    , jsonValidator = require('is-my-json-valid')
    , mergeJSON = require('lodash/merge')
    , lodashClone = require('lodash/clone')
    , responseSchema = require('./responseSchemas/200.json')
    , login = require('./loginWithCallback')
    , getRequest = require('./getRequest')
    ;

var username = "newUser" + Date.now()
    , password = "passW0rd"
    , testEnvironment = {
        "url": "http://localhost:9000/",
        "endPoint": "api/users/login",
        "authorization": "Basic " + base64_encode(username + ":" + password)
    }
    ;

var expectedResult = {};

describe('End to End testing on' + JSON.stringify(testEnvironment), function () {
    describe('new user, ' + username + ', login', function () {
        it('should return 200 and an empty body message.', function (done) {
            login(testEnvironment, function (err, res) {
                if (err) {
                    done(err);
                }

                res.statusCode.should.deepEqual(200);

                var jsonValidate = jsonValidator(responseSchema, {verbose: true});
                jsonValidate(res.body).should.be.true("Response body failed schema check: \n" +
                    JSON.stringify(jsonValidate.errors, null, 4));

                res.body.should.deepEqual(expectedResult);

                done();
            });
        });
    });


    describe('user, ' + username + ', logs in after performing get request', function () {
        var getRequestParams = {"firstName":"john", "lastName":"doe"};

        beforeEach(function() {
            var getEnviron = lodashClone(testEnvironment);
            getEnviron.endPoint = 'api/persons/findName';
            mergeJSON(expectedResult, {"persons": {"findName": getRequestParams}});
            getRequest(getEnviron, getReqestParams, function(err, res) {
                if (err) {
                    done(err);
                }
                console.log("GET request: " JSON.stringify(res, null, 2));
                done();
            });
        });

        it('should return 200 and query values', function(done) {
             login(testEnvironment, function (err, res) {
             if (err) {
                 done(err)
             }

             console.log("it test: " + JSON.stringify(res, null, 2));

             res.statusCode.should.deepEqual(200);

             var jsonValidate = jsonValidator(responseSchema, {verbose: true});
             jsonValidate(res.body).should.be.true("Response body failed schema check: \n" + JSON.stringify(jsonValidate.errors, null, 4));

             res.body.should.deepEqual(expectedResult);

             done();

        });
    });
});

以上三个文件应该做的是: 1.创建一个新用户 2. 登录新用户并测试其对没有先前查询参数的响应。 (通过) 3.执行GET请求,然后在before块中打印结果 4.在it块中执行用户打印和测试结果的登录。

但我得到的是这样的:

End to End testing on{"url":"http://localhost:9000/","endPoint":"api/users/login","authorization":"Basic bmV3VXNlcjE0NjY0NDI0OTEzNDc6cGFzc1cwcmQ="}
  new user, newUser1466442491347, login
    ✓ should return 200 and an empty body message. (54ms)

  user, newUser1466442491347, logs in after performing persons/findByName request
it test: [res text]
    1) should return and query values
GET request: [res text]

1 passing
1 failing

     Uncaught AssertionError: expected Object {} to equal Object {
  persons: Object { findByName: Object { firstName: 'joe', lastName: 'jones' } }
 }

可以看出,'it' 块在 before 块完成之前出现在 运行 之前。从我对 mocha 的阅读来看,这不应该发生,因为它会等待 before 和 beforeEach 在 运行ning 'it' 块之前完成。但是,也许 getRequest 的回调在 it 块之后排队?

我做错了什么或误解了什么?

你绝对必须设置你的beforeEach钩子,这样Mocha就知道它是异步的:要么你return对Mocha的承诺,要么你使用done回调。为了使用 done 回调,您必须声明一个接受 done:

的回调
beforeEach(function (done) {

(您可以随意称呼它(例如 finished),只要您保持一致即可(稍后调用 finished())。)