node.js 测试在节点中使用 mocha/supertest 重定向的请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12272228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:16:20  来源:igfitidea点击:

Testing requests that redirect with mocha/supertest in node

node.jsexpressmochasupertest

提问by Feech

I can't seem to get the following integration test to pass in an express project using mocha, supertest, and should(and coffeescript).

我似乎无法通过使用mochasupertestshould(和coffeescript)的快速项目来通过以下集成测试。



The test

考试

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()


Relevant application code

相关应用代码

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


Failure

失败

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


Obviously, the application code doesn't do anything useful. I'm just trying to get the test to pass.

显然,应用程序代码没有做任何有用的事情。我只是想让测试通过。

Putting the expectation (res.text.should.include('logged in')) outside the end function and inside the expectfunction yields the same results. I've also tried a variation of the function calls, for example removing the .type('form')call, and using .send(user: 'username', password: 'password')instead of the two .field()calls.

将期望值 ( res.text.should.include('logged in')) 放在 end 函数外和函数内会expect产生相同的结果。我还尝试了函数调用的变体,例如删除.type('form')调用,并使用.send(user: 'username', password: 'password')而不是两个.field()调用。

If it means anything, sending a curl POST request to the the app when it's running locally yields the same output (Moved Temporarily. Redirecting to //127.0.0.1:3456/login)

如果这意味着什么,当应用程序在本地运行时向应用程序发送 curl POST 请求会产生相同的输出 ( Moved Temporarily. Redirecting to //127.0.0.1:3456/login)

I have a feeling this is a trivial error. Possibly something I'm forgetting in the application code or the test code.

我有一种感觉,这是一个微不足道的错误。可能是我在应用程序代码或测试代码中忘记了一些东西。

Any suggestions?

有什么建议?

EDIT 1:It's also worth noting that when clicking the submit button in the browser I get the expected results (a flash message).

编辑 1:还值得注意的是,当单击浏览器中的提交按钮时,我得到了预期的结果(一条 Flash 消息)。

EDIT 2:Further investigation shows the output of anyredirect results in the Moved Temporarily. Redirecting to ...response body. This makes me wonder if there is a problem in the way I'm exporting the app in app.js.

编辑 2:进一步调查显示响应正文中任何重定向结果的输出Moved Temporarily. Redirecting to ...。这让我想知道我在 app.js 中导出应用程序的方式是否有问题。

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

module.exports = app;

采纳答案by Feech

For anyone who comes across this page, the answer to this question is pretty simple. The Moved Temporarily.response body is what is returned from supertest. See the issuefor more details.

对于任何遇到此页面的人来说,这个问题的答案非常简单。该Moved Temporarily.响应体就是从supertest返回。有关更多详细信息,请参阅问题

To summarize, I ended up doing something like this.

总而言之,我最终做了这样的事情。

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()

Just check that the response header locationis what you expect it to be. Testing for flash messages and view specific integration tests should be done using another method.

只需检查响应标头location是否符合您的预期。应使用另一种方法来测试 Flash 消息和查看特定的集成测试。

回答by Blacksonic

There is built-in assertion for this in supertest:

对此有内置断言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)

回答by super_noobling

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()

The redirects()will follow the redirect so you can do your usual view tests.

redirects()会执行重定向,所以你可以做你通常的看法测试。

回答by JohnnyCoder

I was trying to write some integration tests for requests that redirected as well, and found a good example by the author of the module himself here.

我试图为重定向的请求编写一些集成测试,并在此处找到了模块作者本人的一个很好的例子。

In TJ's example, he's using chaining, so I used something like that as well.

在 TJ 的例子中,他使用了链接,所以我也使用了类似的东西。

Consider a scenario in which a logged-in user is redirectedto the home page when he or she logs out.

考虑一个已登录用户在注销时被重定向到主页的场景。

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();
        });
    });
});

Depending on how many redirects you have, you might have to nest a few callbacks, but TJ's example should suffice.

根据您有多少重定向,您可能需要嵌套一些回调,但 TJ 的示例应该足够了。