【问题标题】:testing multiple http request using mocha使用 mocha 测试多个 http 请求
【发布时间】:2020-03-06 19:12:02
【问题描述】:

我已经尝试解决这个问题好几天了; 使用 mocha 为这个案例创建测试:

app.post('/approval', function(req, response){
request.post('https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state + '?private_token=blabla', function (error, resp, body) {
    if (resp.statusCode == 201) {
                //do something
            } else {
                response.send("failed"), response.end();
            }
        });  
    } else {
        response.send("failed"), response.end();
    }
});

});

我尝试了几种方法,使用 supertest 来测试 '/approval' 并使用 nock 来测试对 git api 的 post 请求。但它总是把“statusCode”变成未定义的。我认为这是因为 index.js 中对 git api 的请求不在某个函数内(?) 所以我不能实现这样的事情: https://codeburst.io/testing-mocking-http-requests-with-nock-480e3f164851https://scotch.io/tutorials/nodejs-tests-mocking-http-requests

    const nockingGit = () => {
    nock('https://git.ecommchannel.com/api/v4/users')
        .post('/1/yes', 'private_token=blabla')
        .reply(201, { "statusCode": 201 });
};

it('approval', (done) => {
let req = {
    content: {
        id: 1,
        state: 'yes'
    },
    _id: 1
}
request(_import.app)
    .post('/approval')
    .send(req)
    .expect(200)
    .expect('Content-Type', /html/)
    .end(function (err, res) {
        if (!err) {
            nockingGit();  
        } else {
            done(err);
        }
    });
done();

})

然后我尝试使用supertest作为promise

    it('approve-block-using-promise', () => {
       return promise(_import.app)
        .post('/approval')
        .send(req = {
            content: {
                id: 1,
                state: 'yes'
            },
            _id: 1
        })
        .expect(200)
        .then(function(res){
            return promise(_import.app)
            .post("https://git.ecommchannel.com/api/v4/users/")
            .send('1/yes', 'private_token=blabla')
            .expect(201);
        })
})

但它给出了错误:ECONNEREFUSED:连接被拒绝。我没有找到解决该错误的任何解决方案。一些消息来源说它需要 done() .. 但它给出了另一个错误消息,'确保调用了“done()”>。

那么我找到了另一种方法,使用异步 (https://code-examples.net/en/q/141ce32)

    it('should respond to only certain methods', function(done) {
    async.series([
        function(cb) { request(_import.app).post('/approval')
        .send(req = {
            content: {
                id: 1,
                state: 'yes'
            },
            _id: 1
        })
        .expect(200, cb); },
        function(cb) { request(_import.app).post('/https://git.ecommchannel.com/api/v4/users/').send('1/yes', 'private_token=blabla').expect(201, cb); },
    ], done);
});

它给出了这个错误:预期 201“已创建”,得到 404“未找到”。好吧,如果我在浏览器中打开https://git.ecommchannel.com/api/v4/users/1/yes?private_token=blabla,它确实会返回 404。但我期望的是我已经从单元测试中注入了对 201 的响应;所以无论实际响应是什么,statusCode 都应该是 201,对吧? 但是既然它给出了那个错误,这是否意味着单元测试真的将请求发送到api? 请帮我解决这个问题;如何测试我分享的第一个代码。 我真的是单元测试的新手。

【问题讨论】:

  • 您能否更新您的问题以包含测试的nock 部分。此外,在您的第一个测试示例中,您向本地应用程序发出了两个请求。对您的应用的第一个或第二个请求是错误的吗?
  • 嗨,马特,我已将 nock 部分包含在问题中。我使用 supertest 作为 promise 的测试在第二个请求时出错。

标签: unit-testing mocha.js supertest nock supertest-as-promised


【解决方案1】:

您发布的代码有一些问题,我会尝试将它们列出来,但我还在下面提供了一个完整的传递示例。

首先,您在控制器中调用 git.ecommchannel,这是一个没有正文的 POST。虽然这不会导致您看到的错误并且在技术上并不正确,但这很奇怪。所以你应该仔细检查你应该发送的数据是什么。

接下来,我假设这是您创建问题时的复制/粘贴问题,但控制器中请求的回调不是有效的 JS。括号不匹配,发送“失败”两次。

您的 Nock 设置有两个问题。首先nock 的参数应该只有原点,没有路径。所以/api/v4/users 必须移动到post 方法的第一个参数中。另一个问题是传递给post 的第二个参数是POST 正文的可选匹配项。如上所述,您当前没有发送正文,因此 Nock 将始终无法匹配并替换该请求。在下面的示例中,private_token 已被移动以匹配请求的查询字符串,正如所显示的那样。

nockingGit 的呼叫发生得太晚了。在您使用 Supertest 调用您的 Express 应用程序之前,Nock 需要注册模拟。你已经在 end 方法中调用它,到那时为时已晚。

标记为approve-block-using-promise 的测试在第二次调用该应用时出现问题。它通过 Express 应用程序上的 Supertest 调用 post,但是,post 方法的第一个参数是您对应用程序发出的请求的路径。它与对git.ecommchannel 的调用无关。因此,在这种情况下,您的 Express 应用应该返回 404 Not Found。

const express = require('express')
const nock = require('nock')
const request = require('request')
const supertest = require('supertest')

const app = express()
app.use(express.json())

app.post('/approval', function(req, response) {
  const url = 'https://git.ecommchannel.com/api/v4/users/' + req.body.content.id + '/' + req.body.content.state
  request.post({
      url,
      qs: {private_token: 'blabla'}
      // body: {} // no body?
    },
    function(error, resp, body) {
      if (error) {
        response.status(500).json({message: error.message})
      } else if (resp.statusCode === 201) {
        response.status(200).send("OK")
      } else {
        response.status(500).send("failed").end();
      }
    });
});

const nockingGit = () => {
  nock('https://git.ecommchannel.com')
    .post('/api/v4/users/1/yes')
    .query({private_token: 'blabla'})
    .reply(201, {"data": "hello world"});
};

it('approval', (done) => {
  const reqPayload = {
    content: {
      id: 1,
      state: 'yes'
    },
    _id: 1
  }

  nockingGit();

  supertest(app)
    .post('/approval')
    .send(reqPayload)
    .expect(200)
    .expect('Content-Type', /html/)
    .end(function(err) {
      done(err);
    })
})

【讨论】:

  • 嗨,马特感谢您的回复。我真的很感激。现在工作正常:) 但我目前面临另一个问题.. 它仍然是关于诺克的。你能看看我的问题吗>stackoverflow.com/questions/58951664/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 2021-07-24
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多