2017-01-12 2 views
0

Я пытаюсь использовать нок для перехвата/издевки некоторого HTTP-трафика в моем приложении для целей тестирования. Наше приложение проверяет подлинность на одном из наших сайтов, и мне нужен нок для имитации HTTP 200 (с данными JSON) и HTTP 401 (без данных) для проверки поведения, когда пользователь находится или не зарегистрирован там (соответственно) ,Как сделать Nock и Mocha хорошо вместе?

У меня есть два теста, которые работают правильно, когда запускаются в одиночку, но если я запускаю весь набор тестов, один из них всегда терпит неудачу. Я понимаю, что nock - это общее состояние, потому что оно изменяет, как node.js сам обрабатывает сетевой трафик, и я предполагаю, что это является причиной состояния гонки, но я не могу быть единственным человеком, который когда-либо использовал два разных перехватчика нока для одного и того же запроса в два разных теста, поэтому я знаю, что чего-то не хватает.

Может ли кто-нибудь помочь мне разобраться, почему эти тесты наступают друг на друга?

Мой вопрос связан с How to retest same URL using Mocha and Nock?, но я сделал то, что предложил там, и они не помогли.

Мои тестовые файлы (которые, опять же, как работать хорошо, если вызывать по отдельности, но не при запуске в рамках одного и того же тестового прохода) выглядит следующим образом:

import { expect } from 'chai'; 
import nock from 'nock'; 

import * as actionTypes from '../../src/constants/action-types'; 
import * as panoptes from '../../src/services/panoptes'; 

import { user } from '../modules/users/test-data'; 

const stagingHost = 'https://my-staging-server.org'; 

describe('Panoptes',() => { 
    afterEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    beforeEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    describe('with a valid user', function (done) { 
    let lastAction = null; 

    const scope = nock(stagingHost) 
     .get(/^\/oauth\/authorize/) 
     .reply(302, '', { 
     'location': 'https://localhost:3000', 
     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 
     'X-Frame-Options': 'SAMEORIGIN', 
     'X-XSS-Protection': '1; mode=block', 
     }); 

    scope 
     .get(/^\/api\/me/) 
     .reply(200, { 
     users: [user], 
     }); 

    panoptes.checkLoginUser((action) => { lastAction = action; }).then(() => { 
     nock.removeInterceptor(scope); 
     done(); 
    }); 

    it('should know when somebody is logged in', function() { 
     expect(lastAction).to.not.be.null; 
     expect(lastAction.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(lastAction.user).to.not.be.null; 
     expect(lastAction.user.id).to.equal(user.id); 
     expect(lastAction.user.login).to.equal(user.login); 
    }); 
    }); 
}); 

и

import { expect } from 'chai'; 
import nock from 'nock'; 

import * as actionTypes from '../../src/constants/action-types'; 
import * as panoptes from '../../src/services/panoptes'; 

const stagingHost = 'https://my-staging-server.org'; 

describe('Panoptes',() => { 
    afterEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    beforeEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    describe('with no user', function (done) { 
    let lastAction = null; 

    const scope = nock(stagingHost) 
     .get(/^\/oauth\/authorize/) 
     .reply(302, '', { 
     'Cache-Control': 'no-cache', 
     'location': 'https://my-staging-server.org/users/sign_in', 
     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 
     'X-Frame-Options': 'SAMEORIGIN', 
     'X-XSS-Protection': '1; mode=block', 
     }); 

    scope 
     .get(/^\/api\/me/) 
     .reply(401); 

    panoptes.checkLoginUser((action) => { lastAction = action; }).then(() => { 
     nock.removeInterceptor(scope); 
     done(); 
    }); 

    it('should know that nobody is logged in', function() { 
     expect(lastAction).to.not.be.null; 
     expect(lastAction.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(lastAction.user).to.be.null; 
    }); 
    }); 
}); 
+0

Какую ошибку вы видите при совместном тестировании обоих тестов? –

+0

У меня нет ошибки, на самом деле, это просто, что второй тест терпит неудачу, когда он пройдет. Похоже, что на второе испытание влияет макет из первого теста. –

ответ

0

Я думаю, что проблема не в нокауте, а с порядком исполнения вашего хода мокко-крюка:

Возьмем следующий пример:

describe('Panoptes',() => { 

    afterEach(function() { 
    console.log('ORDER: after each'); 
    }); 

    beforeEach(function() { 
    console.log('ORDER: before each'); 
    }); 

    describe('with a valid user', function() { 

    console.log('ORDER: with a valid user'); 

    it('should know when somebody is logged in', function() { 
     console.log('ORDER: should know when somebody is logged in'); 
    }); 

    }); 

    describe('with no user', function() { 

    console.log('ORDER: with no user'); 

    it('should know that nobody is logged in', function() { 
     console.log('ORDER: should know that nobody is logged in'); 
    }); 

    }); 

}); 

Когда мы запускаем его, мы получаем следующий порядок на выходе:

ORDER: with a valid user 
ORDER: with no user 
ORDER: before each 
ORDER: should know when somebody is logged in 
ORDER: after each 
ORDER: before each 
ORDER: should know that nobody is logged in 
ORDER: after each 

afterEach/beforeEach работает до и после каждого it, однако describe тело получает оценку, прежде чем эти крючки называются. Вы должны обернуть каждый из ваших носков внутри before. (Также describe не использует done аргумент)

Что-то, как это должно работать:

describe('with no user', function() { 

    before(function() { 
    const scope = nock(stagingHost) 
     .get(/^\/oauth\/authorize/) 
     .reply(302, '', { 
     'Cache-Control': 'no-cache', 
     'location': 'https://my-staging-server.org/users/sign_in', 
     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 
     'X-Frame-Options': 'SAMEORIGIN', 
     'X-XSS-Protection': '1; mode=block', 
     }); 

    scope 
     .get(/^\/api\/me/) 
     .reply(401); 
    }); 


    it('should know that nobody is logged in', function (done) { 
    panoptes.checkLoginUser((action) => { 
     expect(action).to.not.be.null; 
     expect(action.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(action.user).to.be.null; 
     done(); 
    }); 
    }); 

}); 
+0

Большое вам спасибо за ваше предложение! Я собираюсь попробовать и прокомментировать, как только увижу, разрешит ли это проблему. –

+0

Это то, что мне нужно. К сожалению, мой тест все еще терпит неудачу, но теперь ошибка в нашем коде, и потому, что я раньше не тестировал, я этого не видел! –

+0

Рад, что это сработало! Удачи! –

0

Я использовал ответ sanketh-Катта, который я даю кредит для решения, но слегка модифицировал it блок , поэтому я в том числе мой код для полноты:

it('should know when somebody is logged in', function(done) { 
    panoptes.checkLoginUser((action) => { 
    try { 
     expect(action).to.not.be.null; 
     expect(action.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(action.user).to.not.be.null; 
     expect(action.user.id).to.equal(user.id); 
     expect(action.user.login).to.equal(user.login); 
     done(); 
    } catch (ex) { 
     done(ex); 
    } 
    }); 
}); 

Раньше, когда один из тестов потерпит неудачу, то done() вызов никогда не будет достигнута, и поэтому я получаю сообщение о том, что тест был истекло ины чад конкретного сбоя.

+0

Возможно, вам захочется взглянуть на [chai-as-обещанный] (https: // github.com/domenic/chai-as-обещанный), который решает эту точную проблему. –

Смежные вопросы