简体   繁体   English

如何使用nock截取请求,无论其主体如何

[英]How to use nock to intercept requests regardless of body

I'm trying to use nock in my tests to intercept the request calls i'm making from the native https module in Node.js. 我正在尝试在测试中使用nock来拦截我从Node.js中本机https模块发出的请求调用。 I'm using Promise.all to make two requests to the external server. I'm using Promise.all向外部服务器发出两个请求。 I want my tests to intercept the calls, and check some of the form fields to make sure they're filled in as i want. 我希望我的测试拦截呼叫,并检查一些表单字段以确保它们按我的意愿填写。

I have my class setup below (kept the most relevant parts of code in): 我在下面设置了我的课程(保留了代码中最相关的部分):

const archiver = require('archiver');
const { generateKeyPairSync } = require('crypto');
const FormData = require('form-data');
const fs = require('fs');
const https = require('https');

class Platform {
  constructor() {
    this.FILESTORE_USERNAME = process.env.FILESTORE_USERNAME;
    this.FILESTORE_PASSWORD = process.env.FILESTORE_PASSWORD;
  }

  store(serviceName) {
    const { publicKey, privateKey } = this._generateKeys();

    return Promise.all([this._postKey(publicKey), this._postKey(privateKey)])
      .then(() => {
        return this._zipKeys(publicKey, privateKey, serviceName);
      })
      .catch((err) => {
        throw err;
      });
  }

  _postKey(key) {
    const options = this._getOptions();
    const keyName = (key.search(/(PUBLIC)/) !== -1) ? 'publicKey' : 'privateKey';
    const form = new FormData();
    form.append('file', key);
    form.append('Name', keyName);
    form.append('MimeMajor', 'application');
    form.append('MimeMinor', 'x-pem-file');
    form.append('Extension', (keyName == 'publicKey') ? 'pub' : '');
    form.append('FileClass', 'MFS::File');
    options.headers = form.getHeaders();
    options.headers.Authorization = 'Basic ' + Buffer.from(this.FILESTORE_USERNAME + ':' + this.FILESTORE_PASSWORD).toString('base64');

    return new Promise((resolve, reject) => {
      let post = https.request(options, (res) => {
        let data = '';
        if (res.statusCode < 200 || res.statusCode > 299) {
          reject(new Error('File Storage API returned a status code outside of acceptable range: ' + res.statusCode));
        } else {
          res.setEncoding('utf8');
          res.on('data', (chunk) => {
            data += chunk;
          });

          res.on('error', (err) => {
            reject(err);
          });

          res.on('end', () => {
            if (data) {
              resolve(JSON.parse(data));
            } else {
              resolve();
            }
          });
        }
      });
      post.on('error', (err) => {
        reject(err);
      });
      form.pipe(post);
      post.end();

    });
  }

  _getOptions() {
    return {
      hostname: 'api.example.com',
      path: '/media/files/',
      method: 'POST',
    };
  }
}

module.exports = Platform;

And then, my testing code looks like the below. 然后,我的测试代码如下所示。 I'm using mocha, sinon, chai, sinon-chai and nock. 我正在使用摩卡咖啡,西农,柴,西农柴和诺克。

const Platform = require('/usr/src/app/api/Services/Platform');
const crypto = require('crypto');
const fs = require('fs');
const nock = require('nock');
const yauzl = require('yauzl');

describe('Platform', function() {
  let platform;
  beforeEach(() => {
    platform = new Platform();
  });
  afterEach(() => {
    const list = fs.readdirSync('/usr/src/app/api/Services/data/');
    list.forEach((file) => {
      fs.unlink('/usr/src/app/api/Services/data/' + file, (err) => {
        if (err) throw err;
      });
    });
    nock.cleanAll();
  });
  after(() => {
    nock.restore();
  });
  describe('store', function() {
    it('should post each generated key to an external storage place', async function() {
      this.timeout(5000);
      // const stub = sinon.stub(platform, '_postKey').resolves();
      const scope = nock('https://api.example.com')
        .persist()
        .post('/media/files/', (body) => {
          // console.log(body);
        })
        .reply(200);

      let serviceName = 'test';
      let actual = await platform.store(serviceName)
        .catch((err) => {
          (() => { throw err; }).should.not.throw();
        });

      console.log(scope);
      // expect(stub.callCount).to.equal(2);
      expect(actual).to.be.a('string');
      expect(actual).to.include(serviceName + '.zip');
      // stub.reset();

    });
  });
});

The problem I am coming across is this error that is thrown when running my tests: 我遇到的问题是运行测试时引发的此错误:

AssertionError: expected [Function] to not throw an error but 'Error: Nock: No match for request {\\n "method": "POST",\\n "url": " https://api.example.com/media/files/ ",\\n "headers": {\\n AssertionError:预期[Function]不会抛出错误,而是'Error:Nock:请求不匹配{\\ n“ method”:“ POST”,\\ n“ url”:“ https://api.example.com/media / files / “,\\ n”标题“:{\\ n
"content-type": "multipart/form-data; boundary=--------------------------363749230271182821931703",\\n “ content-type”:“ multipart / form-data; boundary = -------------------------- 363749230271182821931703”,\\ n
"authorization": "Basic abcdef1224u38454857483hfjdhjgtuyrwyt="\\n },\\n "body": "----------------------------363749230271182821931703\\r\\nContent-Disposition: form-data; name=\\"file\\"\\r\\n\\r\\n-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq+QnVOYVjbrHIlAEsEoF\\nZ4sTvqiB3sJGwecNhmgrUp9U8oqgoB50aW6VMsL71ATRyq9b3vMQKpjbU3R2RcOF\\na6mlaBtBjxDGu2nEpGX++mtPCdD9HV7idvWgJ3XS0vGaCM//8ukY+VLBc1IB8CHC\\nVj+8YOD5Y9TbdpwXR+0zCaiHwwd8MHIo1kBmQulIL7Avtjh55OmQZZtjO525lbqa\\nWUZ24quDp38he2GjLDeTzHm9z1RjYJG6hS+Ui0s2xRUs6VAr7KFtiJmmjxPS9/vZ\\nwQyFcz/R7AJKoEH8p7NE7nn/onbybJy+SWRxjXVH8afHkVoC65BiNoMiEzk1rIsx\\ns92woHnq227JzYwFYcLD0W+TYjtGCB8+ks+QRIiV0pFJ3ja5VFIxjn9MxLntWcf2\\nhsiYrmfJlqmpW1DMfZrtt41cJUFQwt7CpN72aix7btmd/q0syh6VVlQEHq/0nDky\\nItv7dqyqZc9NNOMqK9/kXWhbq5cwS21mm+kTGas5KSdeIR0LH7uVtivB+LKum14e\\nRDGascZcXZIVTbOeCxA6BD7LyaJPzXmlMy4spXlhGoDYyVRhpvv2K03Mg7ybiB4X\\nEL1oJtiCFkRX5LtRJv0PCRJjaa3UvfyIuz8bHK4ANxIZqcwZwER+g02gw8iqNfMa\\nDWXpfMJUU8TQuLGWZQaGJc8CAwEAAQ==\\n-----END PUBLIC KEY----- “授权”:“基本abcdef1224u38454857483hfjdhjgtuyrwyt =” \\ n},\\ n“正文”:“ ---------------------------- 363749230271182821931703 \\ r \\ nContent处置:形状数据;名称= \\ “文件\\” \\ r \\ n \\ r \\ n ----- BEGIN PUBLIC KEY ----- \\ nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq + QnVOYVjbrHIlAEsEoF \\ nZ4sTvqiB3sJGwecNhmgrUp9U8oqgoB50aW6VMsL71ATRyq9b3vMQKpjbU3R2RcOF \\ na6mlaBtBjxDGu2nEpGX ++ mtPCdD9HV7idvWgJ3XS0vGaCM / / 8ukY + VLBc1IB8CHC \\ nVj + 8YOD5Y9TbdpwXR + 0zCaiHwwd8MHIo1kBmQulIL7Avtjh55OmQZZtjO525lbqa \\ nWUZ24quDp38he2GjLDeTzHm9z1RjYJG6hS + Ui0s2xRUs6VAr7KFtiJmmjxPS9 / VZ \\ nwQyFcz / R7AJKoEH8p7NE7nn / onbybJy + SWRxjXVH8afHkVoC65BiNoMiEzk1rIsx \\ ns92woHnq227JzYwFYcLD0W + TYjtGCB8 + KS + QRIiV0pFJ3ja5VFIxjn9MxLntWcf2 \\ nhsiYrmfJlqmpW1DMfZrtt41cJUFQwt7CpN72aix7btmd / q0syh6VVlQEHq / 0nDky \\ nItv7dqyqZc9NNOMqK9 / kXWhbq5cwS21mm + kTGas5KSdeIR0LH7uVtivB + LKum14e \\ nRDGascZcXZIVTbOeCxA6BD7LyaJPzXmlMy4spXlhGoDYyVRhpvv2K03Mg7ybiB4X \\ nEL1oJtiCFkRX5LtRJv0PCRJjaa3UvfyIuz8bHK4ANxIZqcwZwER + g02gw8iqNfMa \\ nDWXpfMJUU8TQuLGWZQaGJc8CAwEAAQ == \\ n ----- END PUBLIC KEY ----- \\n\\r\\n----------------------------363749230271182821931703\\r\\nContent-Disposition: form-data; \\ n \\ r \\ n ---------------------------- 363749230271182821931703 \\ r \\ nContent-Disposition:表单数据; name=\\"Name\\"\\r\\n\\r\\npublicKey\\r\\n----------------------------363749230271182821931703\\r\\nContent-Disposition: form-data; 名字= \\ “名称\\” \\ r \\ n \\ r \\ npublicKey \\ r \\ n ---------------------------- 363749230271182821931703 \\ r \\ nContent-Disposition:表单数据; name=\\"MimeMajor\\"\\r\\n\\r\\napplication\\r\\n----------------------------363749230271182821931703\\r\\nContent-Disposition: form-data; 名= \\ “MimeMajor \\” \\ r \\ n \\ r \\ napplication \\ r \\ n ---------------------------- 363749230271182821931703 \\ r \\ nContent-Disposition:表单数据; name=\\"MimeMinor\\"\\r\\n\\r\\nx-pem-file\\r\\n----------------------------363749230271182821931703\\r\\nContent-Disposition: form-data; 名= \\ “MimeMinor \\” \\ r \\ n \\ r \\ NX-PEM-文件\\ r \\ n --------------------------- -363749230271182821931703 \\ r \\ nContent-Disposition:表单数据; name=\\"Extension\\"\\r\\n\\r\\npub\\r\\n----------------------------363749230271182821931703\\r\\nContent-Disposition: form-data; 名= \\ “扩展\\” \\ r \\ n \\ r \\ npub \\ r \\ n ---------------------------- 363749230271182821931703 \\ r \\ nContent-Disposition:表单数据; name=\\"FileClass\\"\\r\\n\\r\\nMFS::File\\r\\n----------------------------363749230271182821931703--\\r\\n"\\n}' was thrown 名字= \\ “FileClass \\” \\ r \\ n \\ r \\ NMFS ::文件\\ r \\ n ---------------------------- 363749230271182821931703-\\ r \\ n“ \\ n}'被抛出

I take it it's because nock expects me to fake out the body for the request to get a correct match? 我认为是因为Nock希望我伪造尸体以请求获得正确的比赛? Is there a way of just looking for requests made to that address, regardless of the body, so I can do my own tests or whatever. 有没有一种方法可以查找针对该地址的请求,而无论其正文如何,因此我可以自己进行测试或执行任何其他操作。

When the post method of a Nock Scope is passed a second argument, it is used to match against the body of the request. 当Nock Scope的post方法传递第二个参数时,它用于与请求的正文进行匹配。

Docs for specifying the request body 用于指定请求正文的文档

In your test, you're passing a function as the second argument, but not returning true so Nock is not considering it a match. 在测试中,您要传递一个函数作为第二个参数,但不返回true因此Nock不会将其视为匹配项。

From the docs: 从文档:

Function: nock will evaluate the function providing the request body object as first argument. 功能:nock将评估提供请求主体对象作为第一个参数的功能。 Return true if it should be considered a match 如果应将其视为匹配项,则返回true

Since your goal is to assert form fields on the request, your best approach would be to leave the function there, do your assertions where the // console.log(body); 由于您的目标是在请求中声明表单字段,因此最好的方法是将函数保留在此处,在// console.log(body);声明// console.log(body); line is, but add return true; 行是,但添加return true; to the end of the function. 到功能的末尾。

You could also return true or false depending on if your form fields match your assertions, but in my experience it makes the error output from the test convoluted. 您还可以返回truefalse这取决于您的表单字段是否与您的断言相匹配,但是根据我的经验,它会使测试的错误输出变得复杂。 My preference is to use standard chai expect() calls and let the assertions bubble errors before Nock continues with request matching. 我的偏好是使用标准的chai expect()调用,并在Nock继续进行请求匹配之前让断言冒泡错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM