使用 mocha 测试多个 http 请求
testing multiple http request using mocha
几天来我一直在努力解决这个问题;
使用 mocha 创建此案例的测试:
app.post('/approval', function(req, response){
request.post('https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state + '?private_token=blabla', function (error, resp, body) {
if (resp.statusCode == 201) {
//do something
} else {
response.send("failed"), response.end();
}
});
} else {
response.send("failed"), response.end();
}
});
});
我尝试了几种方法,使用 supertest 测试“/approval”并使用 nock 测试 post 对 git api 的请求。但它总是转 "statusCode" 是未定义的。我认为那是因为 index.js 中对 git api 的请求不在某个函数内(?)
所以我不能实现这样的事情:
https://codeburst.io/testing-mocking-http-requests-with-nock-480e3f164851 或
https://scotch.io/tutorials/nodejs-tests-mocking-http-requests
const nockingGit = () => {
nock('https://git.ecommchannel.com/api/v4/users')
.post('/1/yes', 'private_token=blabla')
.reply(201, { "statusCode": 201 });
};
it('approval', (done) => {
let req = {
content: {
id: 1,
state: 'yes'
},
_id: 1
}
request(_import.app)
.post('/approval')
.send(req)
.expect(200)
.expect('Content-Type', /html/)
.end(function (err, res) {
if (!err) {
nockingGit();
} else {
done(err);
}
});
done();
})
然后我尝试使用 supertest 作为 promise
it('approve-block-using-promise', () => {
return promise(_import.app)
.post('/approval')
.send(req = {
content: {
id: 1,
state: 'yes'
},
_id: 1
})
.expect(200)
.then(function(res){
return promise(_import.app)
.post("https://git.ecommchannel.com/api/v4/users/")
.send('1/yes', 'private_token=blabla')
.expect(201);
})
})
但它给出错误:ECONNEREFUSED:连接被拒绝。我没有找到任何解决错误的方法。一些消息来源说它需要 done() .. 但它给出了另一条错误消息,“确保 "done()" 被调用” >.<
然后我找到了另一种方法,使用异步 (https://code-examples.net/en/q/141ce32)
it('should respond to only certain methods', function(done) {
async.series([
function(cb) { request(_import.app).post('/approval')
.send(req = {
content: {
id: 1,
state: 'yes'
},
_id: 1
})
.expect(200, cb); },
function(cb) { request(_import.app).post('/https://git.ecommchannel.com/api/v4/users/').send('1/yes', 'private_token=blabla').expect(201, cb); },
], done);
});
它给出了这个错误:预期 201 "Created",得到 404 "Not Found"。好吧,如果我在浏览器中打开 https://git.ecommchannel.com/api/v4/users/1/yes?private_token=blabla,它会显示 return 404。但我期望的是我已经从单元测试中注入了对 201 的响应;所以无论实际响应是什么,statusCode 应该是 201,对吧?
但是既然它给出了那个错误,这是否意味着单元测试真的将请求发送到 api?
请帮我解决这个问题;如何测试我分享的第一个代码。
我真的是单元测试的新手。
您发布的代码有一些问题,我会尝试列出它们,但我还在下面提供了一个完整的通过示例。
首先,您在控制器中对 git.ecommchannel
的调用,它是一个没有主体的 POST。虽然这不会导致您看到的错误并且从技术上讲也不正确,但这很奇怪。所以你应该仔细检查你应该发送的数据是什么。
接下来,我假设这是您创建问题时的一个 copy/paste 问题,但您控制器中请求的回调不是有效的 JS。括号不匹配,发送 "failed" 出现了两次。
您的诺克设置有两个问题。首先,nock
的参数应该只有原点,路径的 none。所以 /api/v4/users
必须移到 post
方法的第一个参数中。另一个问题是传递给 post
的第二个参数是 POST 主体的可选匹配项。如上所述,您当前并未发送正文,因此 Nock 始终无法匹配和替换该请求。在下面的示例中,private_token
已被移动以匹配请求的查询字符串,正如所显示的那样。
nockingGit
的调用发生得太晚了。在您使用 Supertest 调用您的 Express 应用程序之前,Nock 需要注册 mock。你已经在 end
方法中调用了它,到那时已经太晚了。
标记为 approve-block-using-promise
的测试在第二次调用应用程序时出现问题。它通过 Express 应用程序上的 Supertest 调用 post
,但是,该 post
方法的第一个参数是您对应用程序发出的请求的路径。它与调用 git.ecommchannel
无关。因此,在那种情况下,您的 Express 应用应该返回 404 Not Found。
const express = require('express')
const nock = require('nock')
const request = require('request')
const supertest = require('supertest')
const app = express()
app.use(express.json())
app.post('/approval', function(req, response) {
const url = 'https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state
request.post({
url,
qs: {private_token: 'blabla'}
// body: {} // no body?
},
function(error, resp, body) {
if (error) {
response.status(500).json({message: error.message})
} else if (resp.statusCode === 201) {
response.status(200).send("OK")
} else {
response.status(500).send("failed").end();
}
});
});
const nockingGit = () => {
nock('https://git.ecommchannel.com')
.post('/api/v4/users/1/yes')
.query({private_token: 'blabla'})
.reply(201, {"data": "hello world"});
};
it('approval', (done) => {
const reqPayload = {
content: {
id: 1,
state: 'yes'
},
_id: 1
}
nockingGit();
supertest(app)
.post('/approval')
.send(reqPayload)
.expect(200)
.expect('Content-Type', /html/)
.end(function(err) {
done(err);
})
})
几天来我一直在努力解决这个问题; 使用 mocha 创建此案例的测试:
app.post('/approval', function(req, response){
request.post('https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state + '?private_token=blabla', function (error, resp, body) {
if (resp.statusCode == 201) {
//do something
} else {
response.send("failed"), response.end();
}
});
} else {
response.send("failed"), response.end();
}
});
});
我尝试了几种方法,使用 supertest 测试“/approval”并使用 nock 测试 post 对 git api 的请求。但它总是转 "statusCode" 是未定义的。我认为那是因为 index.js 中对 git api 的请求不在某个函数内(?) 所以我不能实现这样的事情: https://codeburst.io/testing-mocking-http-requests-with-nock-480e3f164851 或 https://scotch.io/tutorials/nodejs-tests-mocking-http-requests
const nockingGit = () => {
nock('https://git.ecommchannel.com/api/v4/users')
.post('/1/yes', 'private_token=blabla')
.reply(201, { "statusCode": 201 });
};
it('approval', (done) => {
let req = {
content: {
id: 1,
state: 'yes'
},
_id: 1
}
request(_import.app)
.post('/approval')
.send(req)
.expect(200)
.expect('Content-Type', /html/)
.end(function (err, res) {
if (!err) {
nockingGit();
} else {
done(err);
}
});
done();
})
然后我尝试使用 supertest 作为 promise
it('approve-block-using-promise', () => {
return promise(_import.app)
.post('/approval')
.send(req = {
content: {
id: 1,
state: 'yes'
},
_id: 1
})
.expect(200)
.then(function(res){
return promise(_import.app)
.post("https://git.ecommchannel.com/api/v4/users/")
.send('1/yes', 'private_token=blabla')
.expect(201);
})
})
但它给出错误:ECONNEREFUSED:连接被拒绝。我没有找到任何解决错误的方法。一些消息来源说它需要 done() .. 但它给出了另一条错误消息,“确保 "done()" 被调用” >.<
然后我找到了另一种方法,使用异步 (https://code-examples.net/en/q/141ce32)
it('should respond to only certain methods', function(done) {
async.series([
function(cb) { request(_import.app).post('/approval')
.send(req = {
content: {
id: 1,
state: 'yes'
},
_id: 1
})
.expect(200, cb); },
function(cb) { request(_import.app).post('/https://git.ecommchannel.com/api/v4/users/').send('1/yes', 'private_token=blabla').expect(201, cb); },
], done);
});
它给出了这个错误:预期 201 "Created",得到 404 "Not Found"。好吧,如果我在浏览器中打开 https://git.ecommchannel.com/api/v4/users/1/yes?private_token=blabla,它会显示 return 404。但我期望的是我已经从单元测试中注入了对 201 的响应;所以无论实际响应是什么,statusCode 应该是 201,对吧? 但是既然它给出了那个错误,这是否意味着单元测试真的将请求发送到 api? 请帮我解决这个问题;如何测试我分享的第一个代码。 我真的是单元测试的新手。
您发布的代码有一些问题,我会尝试列出它们,但我还在下面提供了一个完整的通过示例。
首先,您在控制器中对 git.ecommchannel
的调用,它是一个没有主体的 POST。虽然这不会导致您看到的错误并且从技术上讲也不正确,但这很奇怪。所以你应该仔细检查你应该发送的数据是什么。
接下来,我假设这是您创建问题时的一个 copy/paste 问题,但您控制器中请求的回调不是有效的 JS。括号不匹配,发送 "failed" 出现了两次。
您的诺克设置有两个问题。首先,nock
的参数应该只有原点,路径的 none。所以 /api/v4/users
必须移到 post
方法的第一个参数中。另一个问题是传递给 post
的第二个参数是 POST 主体的可选匹配项。如上所述,您当前并未发送正文,因此 Nock 始终无法匹配和替换该请求。在下面的示例中,private_token
已被移动以匹配请求的查询字符串,正如所显示的那样。
nockingGit
的调用发生得太晚了。在您使用 Supertest 调用您的 Express 应用程序之前,Nock 需要注册 mock。你已经在 end
方法中调用了它,到那时已经太晚了。
标记为 approve-block-using-promise
的测试在第二次调用应用程序时出现问题。它通过 Express 应用程序上的 Supertest 调用 post
,但是,该 post
方法的第一个参数是您对应用程序发出的请求的路径。它与调用 git.ecommchannel
无关。因此,在那种情况下,您的 Express 应用应该返回 404 Not Found。
const express = require('express')
const nock = require('nock')
const request = require('request')
const supertest = require('supertest')
const app = express()
app.use(express.json())
app.post('/approval', function(req, response) {
const url = 'https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state
request.post({
url,
qs: {private_token: 'blabla'}
// body: {} // no body?
},
function(error, resp, body) {
if (error) {
response.status(500).json({message: error.message})
} else if (resp.statusCode === 201) {
response.status(200).send("OK")
} else {
response.status(500).send("failed").end();
}
});
});
const nockingGit = () => {
nock('https://git.ecommchannel.com')
.post('/api/v4/users/1/yes')
.query({private_token: 'blabla'})
.reply(201, {"data": "hello world"});
};
it('approval', (done) => {
const reqPayload = {
content: {
id: 1,
state: 'yes'
},
_id: 1
}
nockingGit();
supertest(app)
.post('/approval')
.send(reqPayload)
.expect(200)
.expect('Content-Type', /html/)
.end(function(err) {
done(err);
})
})