我有一个使用Express和Passport的应用。我在Passport中使用Google OAuth2策略。我有一些需要通过此策略登录的路线。
我目前正在与Mocha和Chai进行集成测试,但我不确定如何绕过或使用某些路由所需的OAuth2身份验证。
例如,这是我的一个测试:
it("should list a single item on /items/<id> GET", function(done) {
chai.request(server)
.get('/items/' + id)
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json;
res.body.should.be.a('object');
res.body.should.have.property('description');
done();
});
});
/items/:id
router.get('/items/:id', auth.isLoggedIn, function(req, res) {
var item = getItem();
res.json(item);
});
/items/:id
需要登录。有没有办法绕过登录进行测试,或者模仿用户,我的集成测试会起作用?
答案 0 :(得分:5)
我能用mocha chai chai-http nock和nock-github-oauth测试github OAuth /护照
nock-github-oauth
存根令牌网址
还手动将github用户和电子邮件api调用与来自GitHub API文档的示例进行nock调用
这是我的auth_controller_spec.js
//During the test the env variable is set to test
process.env.NODE_ENV = 'test';
var chai = require('chai');
var chaiHttp = require('chai-http');
var should = chai.should();
var expect = chai.expect
var User = require.main.require('models/User');
// https://gist.github.com/branneman/8048520#7-the-wrapper
var app = require.main.require('app');
chai.use(chaiHttp);
function nockGitHubUserAPI(nock) {
/**
* Intercept `https://api.github.com:443/user` API Call.
*/
nock('https://api.github.com:443')
.filteringPath(/\/user.+/, '/user')
.get('/user')
.reply(200,
{
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"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": "monalisa octocat",
"company": "GitHub",
"blog": "https://github.com/blog",
"location": "San Francisco",
"email": "octocat@github.com",
"hireable": false,
"bio": "There once was...",
"public_repos": 2,
"public_gists": 1,
"followers": 20,
"following": 0,
"created_at": "2008-01-14T04:33:35Z",
"updated_at": "2008-01-14T04:33:35Z"
}
);
/**
* Intercept `https://api.github.com:443/user/emails` API Call.
*/
nock('https://api.github.com:443')
.filteringPath(/\/user\/emails.+/, '/user/emails')
.get('/user/emails')
.reply(200,
[
{
"email": "octocat@github.com",
"verified": true,
"primary": true
}
]
);
}
describe('Auth Controller', (done) => {
var user, nock, github, mockToken, githubHost;
before((done) => {
nock = require('nock');
nock.enableNetConnect('127.0.0.1');
github = require('nock-github-oauth');
nockGitHubUserAPI(nock)
github.nock(done);
})
beforeEach((done) => { //Before each test we reset the database
User.query().del().then(() => {
var params = {name: 'bonzo', authtype: 'github', authid: '12345678'}
// Create a user so the db isn't empty
// May help us uncover odd bugs
new User(params).save()
.then((bonzo) => {
user = bonzo;
done();
})
})
});
after(function(done) {
nock.cleanAll();
done();
});
describe('github link', () => {
it('it should redirect to github.com login / approve page', (done) => {
chai.request(app)
.get('/auth/github')
.redirects(0)
.end((err, res) => {
expect(res.headers['location']).to.match(/^https:\/\/github.com\/login\/oauth\/authorize/);
done();
});
});
});
describe('github callback', () => {
it(' should poll github api for details, upsert the user and log them in', (done) => {
var agent = chai.request.agent(app)
agent.get('/auth/github/callback')
.query({code : '9835b716e83875665b21' })
.end((err, res) => {
// If successful layout displays username on page in (brackets)
expect(res.text).to.match(/\(octocat\)/);
done();
});
});
});
describe('logout', () => {
it('it should end the session and show login', (done) => {
chai.request(app)
.get('/auth/logout')
.end((err, res) => {
expect(res.redirects[0]).to.match(/\/$/);
// If successful layout displays Login links
expect(res.text).to.match(/Login/);
done();
});
});
});
});
答案 1 :(得分:3)
我想通过在我的mocha测试中的请求对象中模拟isAuthenticated来弄清楚如何使这项工作。
var chai = require('chai');
var chaiHttp = require('chaiHttp');
var server = require('../app');
var should = chai.should();
chai.use(chaiHttp);
// Allows the middleware to think we're already authenticated.
server.request.isAuthenticated = function() {
return true;
}
describe('Items', function() {
it('should list all items on / GET', function(done) {
chai.request(server)
.get('/')
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json;
// more tests...
done();
});
});
});
答案 2 :(得分:1)
如果需要,您可以使用自己的方法绕过它,但最好也是测试登录,然后您可以测试要求用户登录的功能。
我之前从未使用过Chai,但你可能会做同样的事情:
var user = null;
it("should log the user in", function(done) {
chai.request(server)
.post('/login', userCredentials)
.end(function(err, res) {
res.should.have.status(200);
user = res.body;
done();
});
});