I'm not sure if this is a bug, or if I am setting up my test incorrectly.
Tested on both Node v9.2.0 and Node v8.9.4.
Development machine is macOS Sierra 10.12.6 (16G1212), TravisCI is Ubuntu 14.04.5 LTS
// package.json
{
"dependencies": {
"apollo-server-express": "^1.3.2",
"bcrypt": "^1.0.3",
"body-parser": "^1.18.2",
"cors": "^2.8.4",
"crypto-js": "^3.1.9-1",
"dataloader": "^1.4.0",
"express": "^4.16.2",
"graphql": "^0.13.1",
"graphql-redis-subscriptions": "^1.4.0",
"graphql-subscriptions": "^0.5.7",
"graphql-tools": "^2.21.0",
"jsonwebtoken": "^8.1.1",
"mongodb": "^3.0.2",
"nodemailer": "^4.4.2",
"subscriptions-transport-ws": "^0.9.5"
},
"devDependencies": {
"apollo-cache-inmemory": "^1.1.9",
"apollo-client": "^2.2.5",
"apollo-link": "^1.1.0",
"apollo-link-http": "^1.3.3",
"axios": "^0.18.0",
"coveralls": "^3.0.0",
"eslint": "^4.18.0",
"graphql-tag": "^2.8.0",
"jest": "^22.4.0",
"jest-cli": "^22.4.0",
"mockdate": "^2.0.2",
"node-fetch": "^2.0.0",
"ws": "^4.0.0"
}
}
I am trying to write some tests for my subscriptions. I have verified that the subscription works using GraphiQL, as well as with my React application that consumes the endpoint.
GraphiQL Verification

https://giphy.com/gifs/ORUfxwVT3sS7ItFmwu (higher quality than gif)
I can't seem to get this working for my integration tests.
I can verify that my subscription is connecting to the /subscriptions endpoint properly, because my code coverage analysis shows that the SubscriptionServer.onConnect method is being called when the failing subscription test is added. I don't see my subscription resolvers marked as having run though. (See the code coverage link at the bottom?)
Test Code
"use strict";
const { ApolloClient } = require("apollo-client");
const { InMemoryCache } = require("apollo-cache-inmemory");
const { ApolloLink } = require("apollo-link");
const { createHttpLink } = require("apollo-link-http");
const gql = require("graphql-tag");
const fetch = require("node-fetch");
const { SubscriptionClient } = require("subscriptions-transport-ws");
const WebSocket = require("ws");
const start = require("../../src/index");
const testHelper = require("../testhelper");
const { PORT } = require("../../src/constants");
const GRAPHQL_SUBSCRIPTIONS_ENDPOINT = `ws://localhost:${PORT}/subscriptions`;
const GRAPHQL_HTTP_ENDPOINT = `http://localhost:${PORT}/graphql`;
let server = null;
let networkInterface = null;
let client = null;
beforeAll(async done => {
await testHelper.initializeTestState();
const resolverUser = await testHelper.createTestUser({
username: "subscriber",
rawPassword: "supersecret123",
email: "[email protected]"
});
const jwt = await testHelper.getJWT({
rawPassword: "supersecret123",
email: resolverUser.email
});
server = await start();
networkInterface = new SubscriptionClient(
GRAPHQL_SUBSCRIPTIONS_ENDPOINT,
{ reconnect: true, connectionParams: { authorization: jwt } },
WebSocket
);
const httpLink = createHttpLink({ uri: GRAPHQL_HTTP_ENDPOINT, fetch });
const middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({ headers: { authorization: jwt } });
return forward(operation);
});
const link = middlewareLink.concat(httpLink);
client = new ApolloClient({
networkInterface,
link,
cache: new InMemoryCache()
});
done();
});
afterAll(async done => {
await networkInterface.close();
await server.close();
await testHelper.tearDownTestState(true);
done();
});
describe("Subscriptions", () => {
it("should subscribe to node creations", async done => {
const subscriptionPromise = new Promise((resolve, reject) => {
client
.subscribe({
query: gql`
subscription AllNodesSubcription {
NodeSubscription(filter: { mutation_in: [CREATED] }) {
mutation
node {
title
}
}
}
`
})
.subscribe({
next: resolve,
error: reject
});
});
await client.mutate({
mutation: gql`
mutation createNode(
$dataType: NodeDataType!
$relationType: NodeRelationType!
$title: String!
$content: String!
$parentId: ID
) {
createNode(
dataType: $dataType
relationType: $relationType
title: $title
content: $content
parentId: $parentId
) {
title
}
}
`,
variables: {
dataType: "TEXT",
relationType: "POST",
title: "Test Create Node Resolver",
content: "Test Create Node Resolver Content String!"
}
});
expect(await subscriptionPromise).toEqual({
data: {
NodeSubscription: {
mutation: "CREATED",
node: {
title: "Test Create Node Resolver"
}
}
}
});
done();
});
});
Failure Message
FAIL __test__/schema/subscriptions.test.js
Subscriptions
✕ should subscribe to node creations (75ms)
● Subscriptions › should subscribe to node creations
expect(received).toEqual(expected)
Expected value to equal:
{"data": {"NodeSubscription": {"mutation": "CREATED", "node": {"title": "Test Create Node Resolver"}}}}
Received:
{"data": {"NodeSubscription": null}}
Difference:
- Expected
+ Received
Object {
"data": Object {
- "NodeSubscription": Object {
- "mutation": "CREATED",
- "node": Object {
- "title": "Test Create Node Resolver",
+ "NodeSubscription": null,
},
- },
- },
}
127 | }
128 | });
> 129 | expect(await subscriptionPromise).toEqual({
130 | data: {
131 | NodeSubscription: {
132 | mutation: "CREATED",
at Object.it (__test__/schema/subscriptions.test.js:129:39)
Did you ever find the issue? I am trying the same thing, but cant get my subscriotion working in my jest test.
Update
I found the solution:
I think the problem is that at the time when you post the mutation, the subscription is not established yet. So you need to put in a timeout (I have 100ms) before you send the mutation.
Most helpful comment
Did you ever find the issue? I am trying the same thing, but cant get my subscriotion working in my jest test.
Update
I found the solution:
I think the problem is that at the time when you post the mutation, the subscription is not established yet. So you need to put in a timeout (I have 100ms) before you send the
mutation.