如何使用 chai、sinon 和 mocha 模拟服务器响应

How to mock server response using chai, sinon and mocha

最近写了一个小服务

  1. 向包含服务定义的 xml 文件发出 http 请求,
  2. 将响应从 xml 转换为 json 并解析给定键 json
  3. returns 如果找到给定的键,则为一个对象,
  4. 否则为空数组

相关代码

resolve() {
    return this._makeResolveRequest() // 1.
        .then(this._convertServiceList) // 2. and 3.
        .then(serviceList => this._filterServices(serviceList)); // 4.
}

this._makeResolveRequestreturns一个承诺。

_makeResolveRequest() {
    return new Promise(function (resolve, reject) {
        return request(options, function (error, response, body) {
            if(error) {
                reject(error);
            }
            resolve(body);
        })
    });
}

测试

现在我真的陷入了编写测试的困境,我显然不知道从哪里开始。

我想测试实际的实现并验证链接的方法是否一起正常工作。所以我的测试应该发出一个真正的 http 请求,但响应应该被模拟。模拟响应应该通过所有 "stations"。最后,我期望一个基于提供的模拟数据的对象。

describe("Arguments", function () {

  it("the service should be a string", function () {
    expect(resolver.serviceType).to.be.a('string');
  });

  it("configuration should be a object", function () {
    expect(resolver.options).to.be.a('object');
  });

  it("configuration should have a attribute protocol", function () {
    expect(resolver.options).to.have.property('protocol');
  });

  it("configuration should have a attribute host", function () {
    expect(resolver.options).to.have.property('host');
  });

  it("configuration have a attribute port", function () {
    expect(resolver.options).to.have.property('port');
  });

  it('should use all passed options', function () {
    // .catch() is used here as we do not have a server running
    // which responds properly
    resolver.resolve().catch(function (err) {
      expect(err.options.uri).to.equal('http://localhost:1234/tr64desc.xml');
      expect(err.options.uri).not.to.equal('https://localhost:1234/tr64desc.xml');
      expect(err.options.uri).not.to.equal('https://localhost/tr64desc.xml');
      expect(err.options.uri).not.to.equal('http://lorem.com/tr64desc.xml');
    })
  });

});

问题从这里开始

describe("Service Resolver", function () {
    let resolver = new ServiceResolver('CommonInterfaceService', {
        protocol: 'http',
        host: 'localhost',
        port: '1234'
    });

    it('should return an object of CommonInterfaceService if the was available', function () {
        resolver.resolve() //??
    });
});

这显然会导致以下错误,因为没有服务器 运行 响应请求的 xml 文件。

{ [Error: connect ECONNREFUSED 127.0.0.1:1234]
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 1234 }

您可以使用“nock”来模拟服务器请求+响应(您可以设置应该返回什么响应代码和正文)。

这里有更多教程:https://davidwalsh.name/nock

希望对您有所帮助!