如何使用 chai、sinon 和 mocha 模拟服务器响应
How to mock server response using chai, sinon and mocha
最近写了一个小服务
- 向包含服务定义的 xml 文件发出 http 请求,
- 将响应从
xml
转换为 json
并解析给定键 json
- returns 如果找到给定的键,则为一个对象,
- 否则为空数组
相关代码
resolve() {
return this._makeResolveRequest() // 1.
.then(this._convertServiceList) // 2. and 3.
.then(serviceList => this._filterServices(serviceList)); // 4.
}
this._makeResolveRequest
returns一个承诺。
_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
希望对您有所帮助!
最近写了一个小服务
- 向包含服务定义的 xml 文件发出 http 请求,
- 将响应从
xml
转换为json
并解析给定键json
- returns 如果找到给定的键,则为一个对象,
- 否则为空数组
相关代码
resolve() {
return this._makeResolveRequest() // 1.
.then(this._convertServiceList) // 2. and 3.
.then(serviceList => this._filterServices(serviceList)); // 4.
}
this._makeResolveRequest
returns一个承诺。
_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
希望对您有所帮助!