11

我想测试 REST API 如何处理具有无效 JSON 语法的正文的 POST 请求,例如缺少逗号。我正在使用 node.js 编写 API 测试。我正在使用frisby但我也尝试过supertest。没运气。使用之前的工具,您将请求正文作为 JavaScript 对象传递,因此行不通。我还尝试将无效的 JSON 作为字符串传递,但没有任何运气,因为字符串也是有效的 JSON(下面的示例)。有任何想法吗?

frisby.create('Ensure response has right status')
    .post('http://example.com/api/books', '{"invalid"}', {json: true})
    .expectStatus(400)
    .toss();
4

4 回答 4

6

使用 supertest 和 mocha 包,您可以通过发布无效的 JSON 来测试端点,如下所示:

var request = require('supertest');

describe('Adding new book', function(){
  it('with invalid json returns a 400', function(done){
    request('http://example.com').post('/api/books')
      .send('{"invalid"}')
      .type('json')
      .expect('Content-Type', /json/)
      .expect(400)
      .end(function(err, res) {
          console.log(res.error);
          done();
      });
  });
});

这里的重要一点是type(json)。这会将请求的 Content-Type 设置为 application/json。没有它,supertest/superagent 将默认以 application/x-www-form-urlencoded 形式发送字符串。此外,无效的 JSON 作为字符串而不是 JavaScript 对象提供。

于 2015-02-13T17:31:08.997 回答
3

我从未使用过 Frisby 或 superagent,但我发现这里有两个问题:

1. 使用 POST 方法将无效的 JSON 从客户端传递到服务器。

这是不可能的,因为它很快就会在客户端本身被拒绝,并且在向服务器发出 POST 请求之前会出错。(因为在使用 http 时只有字符串,所以客户端本身会尝试对 JSON 进行字符串化,这样会卡在无效的 JSON 中)

2. 将无效的 JSON 作为字符串传递

示例:使用 JQuery 发布这样的字符串

 $.post("demo_test_post.asp",
    {
        name: 'pqr:{"abc":"abc",}'    // see there is a comma at the end making JSON invalid
    },
    function(data, status){
        alert("Data: " + data + "\nStatus: " + status);
    });

这将有效地将无效的 JSON(在本例中为名称)作为 srting 传递给服务器。但这将要求您在使用JSON.parse()之前将字符串解析为 JSON。当你尝试得到这个时:

SyntaxError:Object.parse 处的意外标记 p(native) 在 Object.app.get.res.send.data [作为句柄] (/home/ubuntu/workspace/TapToBook.js:35:19) 在 next_layer (/home/ubuntu/workspace/node_modules/express/lib /router/route.js:103:13) 在 Route.dispatch (/home/ubuntu/workspace/node_modules/express/lib/router/route.js:107:5) 在 proto.handle.c (/home/ubuntu /workspace/node_modules/express/lib/router/index.js:195:24) 在 Function.proto.process_params (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:251:12) 在下一个 (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:189:19) 在 Layer.staticMiddleware [作为句柄] (/home/ubuntu/workspace/node_modules/express/node_modules/serve-static /index.js:55:61) 在 proto.handle 的 trim_prefix (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:226:17)。c (/home/ubuntu/workspace/node_modules/express/lib/router/index.js:198:9)

因此,无论您使用哪个包Rest,您都可以将无效的 JSON 作为字符串传递,但不能使用它。

于 2015-02-10T12:51:54.403 回答
1

我假设您的测试想要验证服务器正在处理无效的 JSON(并且不会崩溃)。希望返回 400 错误请求。

由于 http 中的 POST 只是一个字符串,因此测试的一个选项是使用要求您提供 JSON 对象的 API。

如果您使用原始节点 http,那么您可以发送您想要的任何无效字符串:

如何在 node.js 中发出 HTTP POST 请求?

还有流行的请求库。

https://github.com/request/request

例如,使用库,您的测试可以从文件中提取无效内容并发布或放置。从他们的文档中:

fs.createReadStream('file.json').pipe(request.put('http://example.com/obj.json'))
于 2015-02-10T13:02:27.807 回答
0

使用 npm 请求库时,这实际上是一个简单的技巧。这是我的成就,它正在发挥作用。

    describe('with invalid JSON, attempt a config api call', () => {
      let response;
      before(async () => {
        const k = "on:true";
        response = await request.put(configURL+ `/0/config/`, {
          json:k,
          headers: {
            authorization: bearer,
            "content-type": "application/json",
          }
        })
      });
      it('should return http 400 OK', () => {
        response.statusCode.should.equal(400);
      });
      it('should have error message as SyntaxError: Unexpected token in JSON body', () => {
        response.body.should.equal("SyntaxError: Unexpected token in JSON body");
      });
    });

注意:这是一个无效的 JSON,因为 ON 没有引号。这将帮助测试人员使用请求库。

于 2019-10-24T08:44:44.250 回答