Тестирование подписок GraphQL Yoga с помощью Jest зависает и вызывает ошибки тайм-аута
Я пытался написать несколько шуточных тестов для подписки на графическую йогу, но, похоже, не могу заставить ее работать, поскольку продолжаю получать ошибки тайм-аута, и, похоже, не могу найти причину тайм-аута.
Мой код GraphQL Yoga ниже:
сервер.js
import {createYoga, createPubSub} from 'graphql-yoga'
import { makeExecutableSchema} from '@graphql-tools/schema';
import { SubscriptionServer} from 'subscriptions-transport-ws';
import { execute, subscribe } from 'graphql';
import {applyMiddleware} from 'graphql-middleware'
import resolvers from './resolvers/index'
import {createServer} from 'node:http'
import gprf from 'graphql-parse-relation-fields'
import dbRelationalFields from "./helpers/db-relational-fields";
import userFragmentMiddleware from './middleware/userFragmentMiddleware'
import typeDefs from './typeDefs';
import prismaContext from './prismaContext';
const pubsub = createPubSub()
const schema = makeExecutableSchema({typeDefs, resolvers})
const schemaWithMiddleware = applyMiddleware(schema, userFragmentMiddleware)
const yoga = createYoga({
schema: schemaWithMiddleware,
context({request}){
return {
pubsub,
gprf,
prisma:prismaContext,
dbRelationalFields,
request
}
},
})
const server = createServer(yoga)
export {server}
index.js
import {server} from './server'
import * as dotenv from 'dotenv'
dotenv.config()
const main = async() => {
let port = process.env.PORT || 4000
server.listen(port, ()=>{
console.log(`the server is up on port: ${port}`)
})
}
main();
Теперь шуточная сторона вещей
getClient.js
import { ApolloClient, InMemoryCache, createHttpLink, split } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { setContext } from '@apollo/client/link/context';
import { WebSocketLink } from '@apollo/client/link/ws';
import { SubscriptionClient } from 'subscriptions-transport-ws';
import WebSocket from 'ws';
const getClient = (jwt = '') => {
const wsLink = new SubscriptionClient(
'ws://localhost:4000/graphql',
{
reconnect: true,
connectionParams: {
authToken: !!jwt ? jwt : null
}
},
WebSocket
);
let uri = 'http://localhost:4000/graphql';
let httpLink = createHttpLink({ uri });
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
authorization: !!jwt ? `Bearer ${jwt}` : ''
}
};
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
authLink.concat(httpLink)
);
return new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
request(operation) {
if (!!jwt === true) {
operation.setContext({ headers: { authorization: `Bearer ${jwt}` } });
}
}
});
};
export { getClient as default };
Файл тестовой операции comment-operation.js
import {gql } from '@apollo/client';
const deleteComment = gql`
mutation deleteComment($id: ID!, $postId: ID!){
deleteComment(id: $id, postId: $postId){
id
text
author {
id
}
post {
id
}
}
}
`
const subscribeToComments = gql`
subscription subscribeToComments($postId: ID!){
comment(postId: $postId){
mutation
data {
id
text
updateCheckField
}
}
}
`
export {deleteComment, subscribeToComments}
Тестовый файл комментариев comment.spec.js
import 'cross-fetch/polyfill'
import React from 'react';
import ReactDOM from 'react-dom';
import bcrypt from 'bcryptjs'
import { execute, subscribe } from '@apollo/client/link/core'
import { gql } from '@apollo/client';
import PrismaContext from '../src/prismaContext'
import { v4 as uuidv4 } from 'uuid';
import seedDatabase, {userOne, userTwo} from './utils/seedDatabase'
import getClient, {wsLink} from './utils/getClient'
import {deleteComment, subscribeToComments} from './utils/comment-operations'
import {deletePost} from './utils/post-operations'
const client = getClient();
beforeEach(seedDatabase)
test('should subscribe to comments for a post', async(done)=>{
const client = getClient(userTwo.jwt)
const variables = {
postId: userTwo.posts[0]["id"]
}
//const observable = client.subscribe({ query: subscribeToComments, variables})
const subscription = client.subscribe({ query: subscribeToComments, variables}).subscribe({
next: (result) => {
// Perform assertions on the received subscription data
expect(result.data.comment.mutation).toBe('DELETED')
expect(result.data.comment.data.updateCheckField).toBe(`${userTwo.comments[1].id}${userOne.user.id}${userTwo.posts[0].id}`)
subscription.unsubscribe();
done();
},
});
//delete a post
const client1 = getClient(userOne.jwt)
const variables1 = {
id: userTwo.comments[1]["id"],
postId: userTwo.posts[0]["id"]
}
client1.mutate({mutation: deleteComment, variables: variables1})
.then((response)=>{
})
.catch((err)=> console.log('nawaooo', err))
})
Сообщение об ошибке: выброшено: «Превышено время ожидания теста в 5000 мс во время ожидания
done()
быть вызванным. Добавьте значение тайм-аута в этот тест, чтобы увеличить время ожидания, если это длительный тест. См. https://jestjs.io/docs/api#testname-fn-timeout».