6
votes

I have an Express-GraphQL API with a query and a mutation which works in GraphiQL, unit tests of query works, but a unit test of mutation returns a 405 error. my GraphQL schema is as follows:

type Subject {
  type: String
}

type Category {
  name: String
}

type SubjectCategories {
  subject: Subject
  categories: [Category]
}

type Query {
    subjectCategories(subjectType: String!): SubjectCategories
}

type Mutation {
    addSubjectCategory(subjectType: String! categoryName: String!): SubjectCategories
}

for simplifying this question, the implementation of these methods just echo back:

echoGetSubjectCategory({subjectType}, context) {
    const subject = new Subject(subjectType);
    const category = new Category("blah");
    const retval = {
      subject,
      categories: [category],
    };
    return retval;
}
echoMutateSubjectCategory({subjectType, categoryName}, context) {
    const subject = new Subject(subjectType);
    const category = new Category(categoryName);
    const retval = {
      subject,
      categories: [category],
    };
    return retval;
}

via Graphiql, everything works:

mutation {
  addSubjectCategory(subjectType: "s1" categoryName: "c1"){
    subject {
      type
    }
    categories {
      name
    }
  }
}

yields

{
  "data": {
    "addSubjectCategory": {
      "subject": {
        "type": "s1"
      },
      "categories": [
        {
          "name": "c1"
        }
      ]
    }
  }
}

and

{
 subjectCategories(subjectType: "s1"){
    subject {
      type
    }
    categories {
      name
    }
  }
}

yields the same.

in my API unit tests (using request from 'supertest-as-promised'), the query returns 200

const req = request(app)
      .get('/graphql')
      .set('Content-Type', 'application/json')
      .set('Accept', 'application/json')
      .send(JSON.stringify({
        query: "query {subjectCategories(subjectType: \"categorized\" ) { subject {type } categories {name} } }",
      }));
const res = await req;
expect(res.statusCode).toBe(200);

but this test fails:

const req = request(app)
  .get('/graphql')
  .set('Content-Type', 'application/json')
  .set('Accept', 'application/json')
  .send(JSON.stringify({
    query: "mutation {addSubjectCategory(subjectType: \"categorized\" categoryName: \"Politics\" ) { subject {type } categories {name} } }",
  }));
const res = await req;
expect(res.statusCode).toBe(200);

the mutation returns 405 the error message is very opaque:

Expected value to be (using ===):
      200
    Received:
      405
at Object.<anonymous> (test/api.test.js:171:28)
      at Generator.next (<anonymous>)
  at step (test/api.test.js:7:368)
  at test/api.test.js:7:528
      at <anonymous>

So how can I form this json payload to make this unit test of express-graphql pass ?

1

1 Answers

10
votes

Queries can be made using both GET and POST requests, while mutations can only be made with POST requests.

Modify your code like this and it should work:

const req = request(app)
  .post('/graphql')
  .set('Content-Type', 'application/json')
  .set('Accept', 'application/json')
  .send({
    query: "mutation {addSubjectCategory(subjectType: \"categorized\" categoryName: \"Politics\" ) { subject {type } categories {name} } }"
  });
const res = await req;
expect(res.statusCode).toBe(200);