2013-07-09 4 views
3

В приложении, построенном с помощью Node.js (CompoundJS + PassportJS), как можно запускать тесты Mocha на контроллерах, которые заблокированы и требуют входа? Я пробовал использовать Superagent, но мне не очень повезло, и для его использования сервер должен запускаться для запуска тестов. Я очень близко подошел к этому методу, но не хочу, чтобы сервер работал для запуска модульных тестов.Как установить тесты Mocha с помощью Node.js и Passport

Я также пробовал, включая паспорт, и используя метод request.login, я оказался в точке, где я продолжал получать ошибку. passport.initialize() промежуточное программное обеспечение не используется.

Я пытаюсь придерживаться сгенерированных тестов CompoundJS, которые отлично работали до тех пор, пока не была задействована аутентификация. CompoundJS по умолчанию тесты В запустить init.js файл, который будет приятно управлять аутентификацией в и каким-то образом сделать доступными для каждого теста контроллера:

require('should'); 
global.getApp = function(done) { 
    var app = require('compound').createServer() 
    app.renderedViews = []; 
    app.flashedMessages = {}; 

    // Monkeypatch app#render so that it exposes the rendered view files 
    app._render = app.render; 
    app.render = function(viewName, opts, fn) { 
     app.renderedViews.push(viewName); 

     // Deep-copy flash messages 
     var flashes = opts.request.session.flash; 
     for (var type in flashes) { 
      app.flashedMessages[type] = []; 
      for (var i in flashes[type]) { 
       app.flashedMessages[type].push(flashes[type][i]); 
      } 
     } 

     return app._render.apply(this, arguments); 
    } 

    // Check whether a view has been rendered 
    app.didRender = function(viewRegex) { 
     var didRender = false; 
     app.renderedViews.forEach(function(renderedView) { 
      if (renderedView.match(viewRegex)) { 
       didRender = true; 
      } 
     }); 
     return didRender; 
    } 

    // Check whether a flash has been called 
    app.didFlash = function(type) { 
     return !!(app.flashedMessages[type]); 
    } 

    return app; 
}; 

Контроллеры/users_controller_test.js

var app, 
    compound, 
    request = require('supertest'), 
    sinon = require('sinon'); 

/** 
* TODO: User CREATION and EDITs should be tested, with PASSPORT 
* functionality. 
*/ 

function UserStub() { 
    return { 
     displayName: '', 
     email: '' 
    }; 
} 

describe('UserController', function() { 
    beforeEach(function(done) { 
     app = getApp(); 
     compound = app.compound; 
     compound.on('ready', function() { 
      done(); 
     }); 
    }); 

    /** 
    * GET /users 
    * Should render users/index.ejs 
    */ 
    it('should render "index" template on GET /users', function(done) { 
     request(app) 
      .get('/users') 
      .end(function(err, res) { 
       res.statusCode.should.equal(200); 
       app.didRender(/users\/index\.ejs$/i).should.be.true; 
       done(); 
      }); 
    }); 

    /* 
    * GET /users/:id 
    * Should render users/index.ejs 
    */ 
    it('should access User#find and render "show" template on GET /users/:id', 
     function(done) { 
      var User = app.models.User; 

      // Mock User#find 
      User.find = sinon.spy(function(id, callback) { 
       callback(null, new User); 
      }); 

      request(app) 
       .get('/users/42') 
       .end(function(err, res) { 
        res.statusCode.should.equal(200); 
        User.find.calledWith('42').should.be.true; 
        app.didRender(/users\/show\.ejs$/i).should.be.true; 

        done(); 
       }); 
     }); 
}); 

Все они не в состоянии с AssertionError: expected 403 to equal 200 или AssertionError: expected false to be true

ответ

0

Я использовал комбинацию издевательского паспорта. Инициализация, тестовый помощник и слушатель на ком pound configure.

Это дало две вещи:

  1. DRY - повторное использование кода beforeEach через тесты контроллеров.
  2. Ненавязчивое тестирование - mock passport.initialize, поэтому мне не пришлось изменять конфигурацию на основе тестирования.

В тест/init.js я добавил метод макете passport.initialize **:

** Найдено его по адресу:

http://hackerpreneurialism.com/post/48344246498/node-js-testing-mocking-authenticated-passport-js

// Fake user login with passport. 
app.mockPassportInitialize = function() { 
    var passport = require('passport'); 
    passport.initialize = function() { 
     return function (req, res, next) { 
      passport = this; 
      passport._key = 'passport'; 
      passport._userProperty = 'user'; 
      passport.serializeUser = function(user, done) { 
       return done(null, user.id); 
      }; 
      passport.deserializeUser = function(user, done) { 
       return done(null, user); 
      }; 
      req._passport = { 
       instance: passport 
      }; 
      req._passport.session = { 
       user: new app.models.User({ id: 1, name: 'Joe Rogan' }) 
      }; 

      return next(); 
     }; 
    }; 
}; 

Затем я добавил helpers.js для каждого контроллера:

module.exports = { 
    prepApp: function (done) { 
     var app = getApp(); 
     compound = app.compound; 
     compound.on('configure', function() { app.mockPassportInitialize(); }); 
     compound.on('ready', function() { done(); }); 
     return app; 
    } 
}; 

Это будет называться в beforeEach каждого контроллера:

describe('UserController', function() { 
    beforeEach(function (done) { 
     app = require('../helpers.js').prepApp(done); 
    }); 
    [...] 
}); 
+0

Спасибо получает сообщение об ошибке, когда первый тест контроллера работает: {[Ошибка: подключение ECONNREFUSED] код: «ECONNREFUSED», ERRNO: «ECONNREFUSED», системный вызов: 'connect'} – Michael

+1

Обязательно запускайте mocha с помощью 'init.js':' mocha test/init.js test/controllers/users_controller.test.js' – absynce

+0

Также проверьте, что функция prepApp вызывается с помощью 'console.log ('In prepApp'); 'строка вверху' prepApp'. – absynce