node.js - 使用 Mocha 和 Chai 测试 Express 和 Passport OAuth2

标签 node.js express mocha.js passport.js chai

我有一个使用 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 需要登录。有没有办法绕过登录进行测试,或者模拟用户认为我的集成测试会起作用?

最佳答案

我能够使用 mocha chai chai-http nock 和 nock-github-oauth 测试 github OAuth/passport

nock-github-oauth stub token url

还使用 GitHub API 文档中的示例手动调用 github 用户和电子邮件 api 调用

这是我的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();
            });
      });
  });

});

完整源代码在这里:https://github.com/stujo/node-express-gamebase

关于node.js - 使用 Mocha 和 Chai 测试 Express 和 Passport OAuth2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38343674/

相关文章:

node.js - 尝试运行 Strapi 会导致模块解析错误

javascript - Restify 和 Angular JS 都位于不同的域中,如何使用 Restify 响应设置 httponly cookie?

javascript - 无法将文件复制到目录

node.js - 快速中间件

node.js - 使 .well-known 目录在 Express 4 中可见

javascript - Jest - 模拟一个返回 Promise 的 React 组件的依赖

node.js - AWS 控制台中的 AWS Node.js Lambda POST 函数

javascript - CSS 文件路径在本地主机和文本编辑器中均不起作用

javascript - Sinon 不 Mocking db-mysql Node.js 库

javascript - sinon: stub 什么时候恢复?