ajax请求node.js_Node.js测试:模拟HTTP请求

ajax请求node.js

Writing tests for an application that relies on external services, say, a RESTful API, is challenging. More often than not, an external resource may require authentication, authorization or may have a rate limiting. Hitting an endpoint for a service hosted in a service like AWS as part of testing would also incur extra charges.

为依赖于外部服务(例如RESTful API)的应用程序编写测试具有挑战性。 外部资源通常可能需要身份验证,授权或可能具有速率限制。 在测试中为服务于AWS之类的服务中的服务命中端点也将产生额外费用。

This quickly goes out of hand when you are running tests a couple of times a day as a team, as well as part of continous integration. Nock, a HTTP mocking and expectations library for Node.js can be used to avoid this.

当您作为一个团队每天进行两次测试时,这会很快失去控制,并且是持续集成的一部分。 Nock ,可以使用Node.js的HTTP模拟和期望库来避免这种情况。

目标 ( Objectives )

By the end of this post, we will have achieved the following.

到本文结束时,我们将实现以下目标。

  • Written a simple Node.js application that makes a HTTP request to an external endpoint.

    编写了一个简单的Node.js应用程序,该应用程序向外部端点发出HTTP请求。
  • Write tests for the application

    为应用编写测试
  • Mock the requests in the test.

    模拟测试中的请求。

设置项目 ( Setting Up The Project )

To get started, create a simple Node.js application by creating an empty folder and running npm init.

首先,通过创建一个空文件夹并运行npm init来创建一个简单的Node.js应用程序。

mkdir nock-tests
cd nock-tests
npm init

安装软件包 (Installing the packages)

Next, we will install the following packages for our application and testing environment.

接下来,我们将为我们的应用程序和测试环境安装以下软件包。

  • Axios - A Promise based HTTP client for the browser and node.js

    Axios-用于浏览器和node.js的基于Promise的HTTP客户端
  • Mocha - A popular Node.js testing framework.

    Mocha-流行的Node.js测试框架。
  • Chai - A BDD / TDD assertion library for Node.js

    Chai -Node.js的BDD / TDD断言库
  • Nock - A HTTP mocking and expectations library for Node.js

    Nock-用于Node.js的HTTP模拟和期望库
npm install --save axios
npm install --save-dev mocha chai nock

设置测试 (Setting up tests)

Our tests will live inside a test directory, Go ahead and create a test directory and create our first test.

我们的测试将位于测试目录中,继续创建测试目录并创建我们的第一个测试。

mkdir test
touch test/index.test.js

Our first test should be pretty straightforward. Assert that true is, well, true.

我们的第一个测试应该非常简单。 断言,正确就是正确。

/test/index.test.js

/test/index.test.js

const expect = require('chai').expect;

describe('First test', () => {
  it('Should assert true to be true', () => {
    expect(true).to.be.true;
  });
}); 

To run our test, we could run the mocha command from our node_modules but that can get annoying. We are instead going to add it as an npm script.

要运行我们的测试,我们可以从node_modules运行mocha命令,但这会很烦人。 相反,我们将其添加为npm脚本。

/package.json

/package.json

{
  "name": "nock-tests",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "node_modules/.bin/mocha"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.16.2"
  },
  "devDependencies": {
    "chai": "^4.0.2",
    "mocha": "^3.4.2",
    "nock": "^9.0.13"
  }
}

At this point, running npm test on your command-line should give you the following result.

此时,在命令行上运行npm test应该会给您以下结果。

$ npm test
> nock-tests@1.0.0 test /Users/username/projects/nock-tests
> mocha
  First test
    ✓ Should assert true to be true
  1 passing (15ms)

We obviously don't have any tests making requests, or a useful request for that matter, but we will be changing that.

显然,我们没有任何测试可以提出要求,也不需要任何有用的要求,但是我们将对此进行更改。

创建一个Node.js应用进行测试 ( Creating A Node.js App To Test )

Let's go ahead and write a simple function that makes a HTTP request to the Github API to get a user by username. Go ahead and create an index.js file in the root and add the following code.

让我们继续编写一个简单的函数,该函数向Github API发出HTTP请求,以按用户名获取用户。 继续,在根目录中创建一个index.js文件,并添加以下代码。

/index.js

/index.js

const axios = require('axios');

module.exports = {
  getUser(username) {
    return axios
      .get(`https://api.github.com/users/${username}`)
      .then(res => res.data)
      .catch(error => console.log(error));
  }
};

测试:错误的方式 ( Testing: The Wrong Way )

Our test will assert that the request made returns an object with specific details. Replace the truthy test we created earlier with the following test for our code.

我们的测试将断言发出的请求将返回具有特定详细信息的对象。 用下面的代码测试替换我们之前创建的真实测试。

const expect = require('chai').expect;

const getUser = require('../index').getUser;

describe('Get User tests', () => {
  it('Get a user by username', () => {
    return getUser('octocat')
      .then(response => {
        //expect an object back
        expect(typeof response).to.equal('object');

        //Test result of name, company and location for the response
        expect(response.name).to.equal('The Octocat')
        expect(response.company).to.equal('GitHub')
        expect(response.location).to.equal('San Francisco')
      });
  });
});

Let's break down the test.

让我们分解一下测试。

  • We import the getUser method from /index.js.

    我们从/index.js导入getUser方法。
  • We then call the function and assert that we get an object back and that the user's name, company and location match.

    然后,我们调用该函数并断言我们返回了一个对象,并且用户的名称,公司和位置匹配。

This should pass on running the test by actually making a request to the Github API. Let's fix this!

这应该通过实际向Github API发出请求来继续运行测试。 让我们解决这个问题!

测试:正确的方法 ( Testing: The Right Way )

Nock works by overriding Node's http.request function. Also, it overrides http.ClientRequest too to cover for modules that use it directly.

Nock通过重写Node的http.request函数来工作。 同样,它也覆盖http.ClientRequest,以覆盖直接使用它的模块。

With Nock, you can specify the HTTP endpoint to mock as well as the response expected from the request in JSON format. The whole idea behind this is that we are not testing the Github API, we are testing our own application. For this reason, we make the assumption that the Github API's response is predictable.

使用Nock,您可以指定要模拟的HTTP端点以及JSON格式的请求所期望的响应。 这背后的全部想法是我们不是在测试Github API,而是在测试我们自己的应用程序。 因此,我们假设Github API的响应是可预测的。

To mock the request, we will import nock into our test and add the request and expected response in the beforeEach method.

为了模拟请求,我们将nock导入到我们的测试中,并在beforeEach方法中添加请求和预期的响应。

/test/index.test.js

/test/index.test.js

const expect = require('chai').expect;
const nock = require('nock');

const getUser = require('../index').getUser;
const response = require('./response');

describe('Get User tests', () => {
  beforeEach(() => {
    nock('https://api.github.com')
      .get('/users/octocat')
      .reply(200, response);
  });

  it('Get a user by username', () => {
    return getUser('octocat')
      .then(response => {
        //expect an object back
        expect(typeof response).to.equal('object');

        //Test result of name, company and location for the response
        expect(response.name).to.equal('The Octocat')
        expect(response.company).to.equal('GitHub')
        expect(response.location).to.equal('San Francisco')
      });
  });
});

The expected response is defined as an export in a separate file.

预期的响应定义为在单独文件中的导出。

/test/response.js

/test/response.js

module.exports = { login: 'octocat',
  id: 583231,
  avatar_url: 'https://avatars0.githubusercontent.com/u/583231?v=3',
  gravatar_id: '',
  url: 'https://api.github.com/users/octocat',
  html_url: 'https://github.com/octocat',
  followers_url: 'https://api.github.com/users/octocat/followers',
  following_url: 'https://api.github.com/users/octocat/following{/other_user}',
  gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}',
  starred_url: 'https://api.github.com/users/octocat/starred{/owner}{/repo}',
  subscriptions_url: 'https://api.github.com/users/octocat/subscriptions',
  organizations_url: 'https://api.github.com/users/octocat/orgs',
  repos_url: 'https://api.github.com/users/octocat/repos',
  events_url: 'https://api.github.com/users/octocat/events{/privacy}',
  received_events_url: 'https://api.github.com/users/octocat/received_events',
  type: 'User',
  site_admin: false,
  name: 'The Octocat',
  company: 'GitHub',
  blog: 'http://www.github.com/blog',
  location: 'San Francisco',
  email: null,
  hireable: null,
  bio: null,
  public_repos: 7,
  public_gists: 8,
  followers: 1840,
  following: 6,
  created_at: '2011-01-25T18:44:36Z',
  updated_at: '2017-07-06T21:26:58Z' };

To test that this is the actual response expected in the test, try editing one of the fields in the response object and run the test again. The tests should fail.

要测试这是测试中期望的实际响应,请尝试编辑响应对象中的字段之一,然后再次运行测试。 测试应该失败。

In my case, I will be changing the name value to Scotch. You should get the error below.

就我而言,我将名称值更改为Scotch 。 您应该在下面得到错误。

Failing test

结论 ( Conclusion )

We have only scratched the surface on what you can do with nock. It has a very detailed documentation on how to use it and it is worth exploring. For instance, If you are writing tests that involve error handling, you could mock error responses with an error message.

我们只是对您使用nock可以做的事情进行了初步介绍。 它具有有关如何使用它的非常详细的文档,值得探讨。 例如,如果您正在编写涉及错误处理的测试,则可以使用错误消息模拟错误响应。

nock('http://www.google.com')
   .get('/cat-poems')
   .replyWithError('something awful happened');

Happy testing!

测试愉快!

翻译自: https://scotch.io/tutorials/nodejs-tests-mocking-http-requests

ajax请求node.js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值