GraphQL端点的400 Bad Requst(我的测试查询出了什么问题?)

时间:2019-12-13 10:19:27

标签: javascript node.js graphql mocha supertest

我主要关注有关how to create a mutation的GraphQL文档。这是我使用GraphQL的第一天。我想为评论创建一个端点。

解决问题

我从摩卡supertest中回来了 400个“错误请求” ,当我尝试运行GraphiQL时,它在错误数组中显示了一条消息,内容为:必须提供查询根类型。” ...但是我 am 包括rootValue

enter image description here

问题可能出在buildSchema上。

// imports (...working fine)

// Comment Interface for TypeScript is here ...and working
// ...

// gaphql schema (The problem could be here.)
const schema = buildSchema(`
    input CommentInput {
        _id: String
        author: String
        text: String
    }
    type Comment {
        _id: String
        author: String
        text: String
    }
    type Mutation {
        createOrUpdateComment(input: CommentInput): Comment
    }
`);

// rootValue
const root = {
    createOrUpdateComment: ({input}: { input: IComment }) => {
       return {
         _id: "id here",
         author: input.author,
         text: input.text
       }
    }
};

export default graphqlHTTP({
    graphiql: true,
    rootValue: root,
    schema
});

此文件被导入,然后在快递服务器的顶层使用,就像comments一样:

app.use("/comments", comments);

工作原理 GraphiQL 确实会在浏览器中的localhost:8080/comments上弹出,所以我很确定Express方面没有任何问题。 (顺便说一下,TypeScript编译就很好。)我还有一个不同的GraphQL api端点,返回“ Hello world!”。在我正在使用Mocha测试的服务器的最高级别上,它通过了(最初失败后),因此我的测试套件似乎运行良好。没有其他环境变量。这就是您在这里看到的。

我要通过的测试(给我404错误请求)是:

// imports (...working fine)

describe("graphQl comments test", () => {

    it("should add a comment", (done) => {

        const query = `mutation createOrUpdateComment($input: CommentInput) {
              _id
              author
              text
          }`;

        const variables = {
              input: {
                  author: "Brian",
                  text: "This is my favorite video of all time."
              }
          };

        request(app)
            .post("/comments")
            .send(JSON.stringify({ query, variables})) // (The problem could be here.)
            .expect(200)
            .end((err, res) => {
                if (err) { return done(err); }
                // tslint:disable-next-line: no-unused-expression
                expect(res.body.data.id).to.exist;
                expect(res.body.data.author).to.equal("Brian");
                expect(res.body.data.text).to.equal("This is my favorite video of all time.");
                done();
            });
    });
});

因为它说“错误的 request ”,所以我在测试中处理queryvariables的方式肯定是问题所在。

问题

我的问题是测试中的查询和变量还是我的buildSchema? ...还是两者?我会怎样写才能使测试通过?

更新

在注释掉导出中的rootValue之后,由于这样说,因为它说“必须提供查询根类型”,因此在 GraphiQL 中发现没有区别。好像rootValue不在那里,即使它在那里。

export default graphqlHTTP({
    graphiql: true,
    // rootValue: root,
    schema
});

一旦我为this Github issue中提到的内容添加了QuerygetComment() GraphiQL 中的错误消息就消失了。不幸的是,该测试仍在发出 400错误请求,因此问题似乎无关。

更新2

我用GraphiQL测试了端点,当我发布以下消息时,它按预期/期望的方式工作:

mutation {
  createOrUpdateComment(input: {_id: "4", author: "Some Author", text: "some unique text"}) {
    _id
    author
    text
  }
}

我正在努力使测试查询相似,但它们不是类似的。这清楚表明问题出在测试本身中,当我记录身体的响应时,我得到以下信息:

enter image description here

所以我的测试的查询字符串有问题。

已解决。

请在下面查看我的答案。

2 个答案:

答案 0 :(得分:1)

GraphQL中有三个操作-查询,变异和订阅。每个操作都有一个与之关联的对象类型。这些称为根类型。默认情况下,这些根类型分别命名为QueryMutationSubscription(这些名称无关紧要,可以为您的特定架构进行更改,但这是默认设置)。根类型用作您对该模式其余部分进行任何查询的入口点,即 root

规范要求需要查询根类型,而其他两个根类型是可选的,可以省略。

该错误与根值无关。实际上,您可能shouldn't be using buildSchema and rootValue in the first place。如错误所示,您尚未在架构中提供查询根类型。模式中唯一包含的根类型是Mutation。您需要添加Query才能解决该错误。

答案 1 :(得分:0)

我在测试中遇到的主要问题是

  • 我正在JSON.string化数据。那是文档的example using fetch中的内容,但是supertest会自动将数据转换为JSON字符串。
  • 我将查询调整为仅一个字符串,未添加任何变量。我想尽快解决这个问题,看看是否可以使用变量发送它,但是我只是想简化事情。
  • 根据丹尼尔·雷登(Daniel Rearden)的建议,我登出了尸体。这是我在测试中没有想到的无价调试建议,因为我只是假设:“嗯,这是错误的,对吧?”咄。不。总会有回应。这帮助我将返回值设置为直线。

这是我最终得到的测试文件:

import { expect } from "chai";
import request = require("supertest");
import app from "../src";

describe("graphQl comments test", () => {

    it("should add a comment", (done) => {

        const query = `mutation {
            createOrUpdateComment(input: {_id: "4", author: "Brian", text: "This is my favorite video of all time."}) {
              _id
              author
              text
            }
          }`;

        request(app)
            .post("/comments")
            .send({query})
            .expect(200)
            .end((err, res) => {
                if (err) { return done(err); }
                // tslint:disable-next-line: no-unused-expression
                expect(res.body.data.createOrUpdateComment._id).to.exist;
                expect(res.body.data.createOrUpdateComment.author).to.equal("Brian");
                expect(res.body.data.createOrUpdateComment.text).to.equal("This is my favorite video of all time.");
                done();
            });
    });
});