39

mochasupertestshould(およびcoffeescript)を使用したエクスプレスプロジェクトで、次の統合テストに合格することができないようです。


テスト

should  = require('should')
request = require('supertest')
app     = require('../../app')

describe 'authentication', ->
  describe 'POST /sessions', ->
    describe 'success', (done) ->
      it 'displays a flash', (done) ->
        request(app)
          .post('/sessions')
          .type('form')
          .field('user', 'username')
          .field('password', 'password')
          .end (err, res) ->
            res.text.should.include('logged in')
            done()

関連するアプリケーションコード

app.post '/sessions', (req, res) ->
  req.flash 'info', "You are now logged in as #{req.body.user}"
  res.redirect '/login'

失敗

1) authentication POST /sessions success displays a flash:
   AssertionError: expected 'Moved Temporarily. Redirecting to //127.0.0.1:3456/login' to include 'logged in'

明らかに、アプリケーションコードは何の役にも立ちません。テストに合格しようとしています。

期待値(res.text.should.include('logged in'))をend関数の外側と関数の内側に置くexpectと、同じ結果が得られます。また、関数呼び出しのバリエーションを試しました。たとえば、呼び出しを削除し、2つの呼び出しの代わりに.type('form')使用します。.send(user: 'username', password: 'password').field()

それが何かを意味する場合、ローカルで実行されているときにアプリにcurl POSTリクエストを送信すると、同じ出力が生成されます(Moved Temporarily. Redirecting to //127.0.0.1:3456/login

これは些細な間違いだと思います。アプリケーションコードやテストコードで忘れているかもしれません。

助言がありますか?

編集1:ブラウザの送信ボタンをクリックすると、期待どおりの結果(フラッシュメッセージ)が得られることにも注意してください。

編集2:さらに調査すると、リダイレクト結果の出力が応答本文に表示Moved Temporarily. Redirecting to ...ます。これにより、app.jsでアプリをエクスポートする方法に問題があるのではないかと思います。

var express = require('express')
var app = express();

module.exports = app;
4

4 に答える 4

30

これには組み込みのアサーションがありますsupertest

should  = require('should')
request = require('supertest')
app     = require('../../app')

describe 'authentication', ->
  describe 'POST /sessions', ->
    describe 'success', ->
      it 'redirects to the right path', (done) ->
        request(app)
          .post('/sessions')
          .send(user: 'username', password: 'password')
          .expect(302)
          .expect('Location', '/home')
          .end(done)
于 2015-11-11T13:50:49.580 に答える
27

このページに出くわした人にとって、この質問への答えは非常に簡単です。応答本体は、Moved Temporarily.スーパーテストから返されるものです。詳細については、問題を参照してください。

要約すると、私はこのようなことをすることになりました。

should  = require('should')
request = require('supertest')
app     = require('../../app')

describe 'authentication', ->
  describe 'POST /sessions', ->
    describe 'success', ->
      it 'redirects to the right path', (done) ->
        request(app)
          .post('/sessions')
          .send(user: 'username', password: 'password')
          .end (err, res) ->
            res.header['location'].should.include('/home')
            done()

応答ヘッダーlocationが期待どおりであることを確認してください。フラッシュメッセージのテストと特定の統合テストの表示は、別の方法を使用して実行する必要があります。

于 2012-09-06T01:34:45.513 に答える
8
describe 'authentication', ->
  describe 'POST /sessions', ->
    describe 'success', (done) ->
      it 'displays a flash', (done) ->
        request(app)
          .post('/sessions')
          .type('form')
          .field('user', 'username')
          .field('password', 'password')
          .redirects(1)
          .end (err, res) ->
            res.text.should.include('logged in')
            done()

redirects()リダイレクトに従うので、通常のビューテストを実行できます。

于 2017-12-23T04:38:25.337 に答える
2

私はリダイレクトされたリクエストに対していくつかの統合テストを書き込もうとしていましたが、ここでモジュールの作成者自身による良い例を見つけました。

TJの例では、彼はチェーンを使用しているので、私もそのようなものを使用しました。

ログインしたユーザーがログアウトしたときにホームページにリダイレクトされるシナリオを考えてみます。

it('should log the user out', function (done) {
  request(app)
    .get('/logout')
    .end(function (err, res) {
      if (err) return done(err);
      // Logging out should have redirected you...
      request(app)
        .get('/')
        .end(function (err, res) {
          if (err) return done(err);
          res.text.should.not.include('Testing Tester');
          res.text.should.include('login');
          done();
        });
    });
});

リダイレクトの数によっては、いくつかのコールバックをネストする必要がある場合がありますが、TJの例で十分です。

于 2013-09-25T00:49:53.830 に答える