7

現在、SailsJS を使用してアプリを作成しています。これまでに行われたことは、「手動で」テストした場合は期待どおりに機能しますが、Mocha でテストした場合は機能しません。

SailsJS testing guideに従って、npm でテストを呼び出してみました。

[...]
"scripts": {
  "start": "node app.js",
  "debug": "node debug app.js",
  "test": "mocha test/bootstrap.test.js test/unit/**/*.test.js"
},
[...]

私のテストディレクトリ構造は次のとおりです。

test
├── bootstrap.test.js
├── mocha.opts
└── unit
    └── controllers
        └── UserController.test.js

ブーストストラップ.test.js:

var Sails = require('sails');
var sails;

before(function(done) {
  Sails.lift(function(err, server) {
    sails = server;
    if (err) return done(err);
    done(err, sails);
  });
});

after(function(done) {
  Sails.lower(done);
});

UserController.test.js:

var request = require('supertest');

describe('UsersController', function() {

  describe('#logout()', function() {
    it('should respond with a 401 status because nobody is logged in', function (done) {
      request(sails.hooks.http.app)
        .put('/user/logout')
        .expect(401, done)
    });
  });

  describe('#signup()', function() {
    it('should create and log in an user', function (done) {
      request(sails.hooks.http.app)
        .post('/user')
        .send({
          firstname: 'foo',
          name: 'bar',
          email: 'foo@bar.com',
          sex: true,
          password: 'foobar',
          birthdate: '01/01/1991',
          phoneNumber: '+33 3 10 10 10'
        })
        .expect(200, done)
    });
  });

  describe('#logout()', function() {
    it('should log out an user', function (done) {
      request(sails.hooks.http.app)
        .put('/user/logout')
        .expect(200, done)
    });
  });

  describe('#login()', function() {
    it('should respond with a 404 status because credentials are invalid', function (done) {
      request(sails.hooks.http.app)
        .put('/user/login')
        .send({
          email: 'bar@foo.com',
          password: 'barfoo'
        })
        .expect(404, done)
    });
  });

  describe('#login()', function() {
    it('should log in an user', function (done) {
      request(sails.hooks.http.app)
        .put('/user/login')
        .send({
          email: 'foo@bar.com',
          password: 'foobar'
        })
        .expect(200, done);
    });
  });

  describe('#login()', function() {
    it('should respond with a 401 status because user is already logged in', function (done) {
      request(sails.hooks.http.app)
        .put('/user/login')
        .send({
          email: 'foo@bar.com',
          password: 'foobar'
        })
        .expect(401, done);
    });
  });
});

最後に、 npm testを呼び出したときの出力は次のとおりです。

> sails@0.0.0 test /Users/fwoelffel/Dev/STOFMA
> mocha test/bootstrap.test.js test/unit/**/*.test.js



  UsersController
    #logout()
debug: false
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'authenticated' disallowed to proceed to the next policy
      ✓ should respond with a 401 status because nobody is logged in (86ms)
    #signup()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: User foo@bar.com signed up and logged in.
      ✓ should create and log in an user (146ms)
    #logout()
debug: false
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'authenticated' disallowed to proceed to the next policy
      1) should log out an user
    #login()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: No user matching bar@foo.com.
      ✓ should respond with a 404 status because credentials are invalid (66ms)
    #login()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: Found user foo@bar.com.
info: foo@bar.com credentials are valid.
      ✓ should log in an user (128ms)
    #login()
debug: null === req.session.authenticated || undefined === req.session.authenticated -> true
debug: req.session -> {"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"}}
info: Policy 'unauthenticated' allowed to proceed to the next policy
info: Found user foo@bar.com.
info: foo@bar.com credentials are valid.
      2) should respond with a 401 status because user is already logged in


  4 passing (1s)
  2 failing

  1) UsersController #logout() should log out an user:
     Error: expected 200 "OK", got 401 "Unauthorized"
      at net.js:1419:10

  2) UsersController #login() should respond with a 401 status because user is already logged in:
     Error: expected 401 "Unauthorized", got 200 "OK"
      at net.js:1419:10



npm ERR! Test failed.  See above for more details.

要約すると、私は auth/unauth API をテストしています。以下はポリシーです。

  • ログインしているユーザーがログインしようとすると、「認証されていない」ポリシーがエラー (401) をスローする必要があります。
  • ログインしているユーザーがサインアップしようとすると、「認証されていない」ポリシーがエラー (401) をスローする必要があります。
  • ログアウトしたユーザーがログアウトしようとすると、「認証済み」ポリシーがエラー (401) をスローする必要があります。

私は何か間違ったことをしているかもしれませんが、それが何であるかは本当にわかりません。この問題を解決するのを手伝ってもらえますか?

さらに詳しい情報が必要な場合は、お問い合わせください。Githubでコードを見つけることができます (テストは失敗しているため、テストは含まれていません) 。

読んでくれてありがとう、良い一日を!

アップデート

elsaar のおかげで、コードを次のように変更しました。

var request = require('supertest');
var agent;

describe('UsersController', function() {

  before(function(done) {
    agent = request.agent(sails.hooks.http.app);
    done();
  })

  describe('#logout()', function() {
    it('should respond with a 401 status because nobody is logged in', function (done) {
      agent
        .put('/user/logout')
        .expect(401, done)
    });
  });

  describe('#signup()', function() {
    it('should create and log in an user', function (done) {
      agent
        .post('/user')
        .send({
          firstname: 'foo',
          name: 'bar',
          email: 'foo@bar.com',
          sex: true,
          password: 'foobar',
          birthdate: '01/01/1991',
          phoneNumber: '+33 3 10 10 10'
        })
        .expect(200, done)
    });
  });

  describe('#logout()', function() {
    it('should log out an user', function (done) {
      agent
        .put('/user/logout')
        .expect(200, done)
    });
  });

  describe('#login()', function() {
    it('should respond with a 404 status because credentials are invalid', function (done) {
      agent
        .put('/user/login')
        .send({
          email: 'bar@foo.com',
          password: 'barfoo'
        })
        .expect(404, done)
    });
  });

  describe('#login()', function() {
    it('should log in an user', function (done) {
      agent
        .put('/user/login')
        .send({
          email: 'foo@bar.com',
          password: 'foobar'
        })
        .expect(200, done);
    });
  });

  describe('#login()', function() {
    it('should respond with a 401 status because user is already logged in', function (done) {
      agent
        .put('/user/login')
        .send({
          email: 'foo@bar.com',
          password: 'foobar'
        })
        .expect(401, done);
    });
  });
});
4

1 に答える 1

5

セッションが永続化されていないと思うので、以前のリクエストでログインしたユーザーは、後のリクエストではログインしません。これは、単体テストのあるべき方法です。したがって、テストを実行する前に、ユーザーが目的の状態 (ログインまたはログアウト) であることを確認する必要があります。

編集- セッションを永続化するには、スーパーテスト エージェントの同じインスタンスを使用する必要があります - https://github.com/visionmedia/supertest/issues/46#issuecomment-58534736

したがって、テストの最初にこれを行い、すべてのテストで同じエージェントを使用します

var supertest = require('supertest');
    agent = supertest.agent(sails.hooks.http.app);

// the use the agent to test your endpoints
于 2015-07-21T08:13:11.460 に答える