如何使Nock和Mocha一起玩好? [英] How do I make Nock and Mocha play well together?

查看:63
本文介绍了如何使Nock和Mocha一起玩好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试使用nock拦截/模拟应用程序中的某些HTTP通信,以进行测试.我们的应用程序向我们的另一个站点进行身份验证,我需要nock模仿一个HTTP 200(带有JSON数据)和一个HTTP 401(没有数据)来分别测试用户登录或未登录时的行为.

I am trying to use nock to intercept/mock some HTTP traffic in my application for testing purposes. Our app authenticates to another one of our sites, and I need nock to imitate an HTTP 200 (with JSON data) and an HTTP 401 (with no data) to test behaviors when the user is or isn't logged in there (respectively).

我有两个测试,它们在单独运行时都可以正常运行,但是如果我运行整个测试套件,则其中一个总是失败.我意识到Nock是共享状态,因为它修改了node.js本身处理网络流量的方式,并且我认为这是争用条件的原因,但是我不能成为唯一曾经在同一请求中使用过两个不同的Nock拦截器的人两种不同的测试,所以我知道我缺少了一些东西.

I have two tests which both work correctly when run alone, but if I run the entire test suite, one of them always fails. I realize that nock is shared state because it modifies how node.js itself handles network traffic and I assume that's the cause of the race condition, but I can't be the only person who's ever used two different nock interceptors for the same request in two different tests, so I know I'm missing something.

有人可以帮助我弄清楚为什么这些测试会互相影响吗?

Can anyone help me figure out why these tests are stepping on each other?

我的问题与如何使用以下方法重新测试相同的URL有关摩卡(Mocha)和纳克(Nock)?

My question is related to How to retest same URL using Mocha and Nock? but I did the things suggested there and they didn't help.

我的测试文件(同样,如果分别调用,它们都可以正常工作,但是当作为同一测试通过的一部分运行时失败):

My test files (which, again, both work fine if called individually, but fail when run as part of the same test pass) look like this:

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;
    });
  });
});

推荐答案

我认为问题不在于nock,而是与您的摩卡挂钩执行顺序有关:

I think the problem is not in nock, but with the order of your mocha hook's execution order:

以这个例子为例:

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');
    });

  });

});

当我们运行它时,我们在输出中获得以下顺序:

When we run it we get the following order on output:

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 主体在这些钩子之前得到评估叫做.您应该将每个Nocks包裹在 before 内.(而且 describe 也不使用 done 参数)

afterEach/beforeEach runs before and after each it, however the describe body gets evaluated before those hooks are called. You should wrap each of your nocks inside a before. (Also describe does not use a done argument)

类似的事情应该起作用:

Something like this should work:

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();
    });
  });

});

这篇关于如何使Nock和Mocha一起玩好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆