Код из beforeEach работает после 'itpec

Я использую mocha и supertest для тестирования службы REST. В этом случае мне нужно проверить, что последующий вход в систему после запроса GET возвращает запрос из этого запроса GET.

  1. логин пользователя
  2. выполнить запрос GET на конечной точке (точках), используя params
  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 перед запуском блока it. Но, возможно, обратный вызов для getRequest ставится в очередь после блока it?

Что я делаю неправильно или недоразумение?

1 ответ

Решение

Вы обязательно должны установить свой beforeEach подключите, чтобы Mocha знал, что он асинхронный: либо вы возвращаете обещание Mocha, либо используете done Перезвоните. Для того, чтобы использовать done обратный вызов, вы должны объявить обратный вызов, который принимает done:

beforeEach(function (done) {

(Вы можете назвать это как угодно (например, finished), пока вы последовательны (звоните finished() потом).)

Другие вопросы по тегам