Skip to content

Commit 25666da

Browse files
committed
Initial commit
0 parents  commit 25666da

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

README.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# apollo-server-integration-testing-fastify
2+
3+
This package exports an utility function for writing apollo-server integration tests:
4+
5+
```js
6+
import { createTestClient } from 'apollo-server-integration-testing';
7+
```
8+
9+
## Usage
10+
11+
This function takes in an apollo server instance and returns a function that you can use to run operations against your schema, and assert on the results.
12+
13+
Example usage:
14+
15+
```js
16+
import { createTestClient } from 'apollo-server-integration-testing-fastify';
17+
import { createApolloServer } from './myServerCreationCode';
18+
19+
const apolloServer = await createApolloServer();
20+
const { query, mutate } = createTestClient({
21+
apolloServer
22+
});
23+
24+
const response = await query(`{ currentUser { id } }`);
25+
26+
expect(response.statusCode).toEqual(200);
27+
28+
// You can access the response object using .json()
29+
expect(response.json()).toEqual({
30+
data: {
31+
currentUser: {
32+
id: '1'
33+
}
34+
}
35+
});
36+
37+
const UPDATE_USER = `
38+
mutation UpdateUser($id: ID!, $email: String!) {
39+
updateUser(id: $id, email: $email) {
40+
user {
41+
email
42+
}
43+
}
44+
}
45+
`;
46+
47+
const mutationResponse = await mutate(UPDATE_USER, {
48+
variables: { id: 1, email: 'nancy@foo.co' }
49+
});
50+
51+
expect(mutationResponse.statusCode).toEqual(200);
52+
53+
// You can access the response object using .json()
54+
expect(mutationResponse.json()).toEqual({
55+
data: {
56+
updateUser: {
57+
email: 'nancy@foo.co'
58+
}
59+
}
60+
});
61+
```
62+
63+
This allows you to test all the logic of your apollo server, including any logic inside of the `context` option that you can pass to the `ApolloServer` constructor.
64+
65+
### Mocking the `Request` object
66+
67+
`createTestClient` automatically mocks the `Request` object that will be passed to the `context` option of your `ApolloServer` constructor, so testing works out of the box.
68+
You can also extend the mocked Request object with additional keys by passing an `extendMockRequest` field to `createTestClient`:
69+
70+
```js
71+
const { query } = createTestClient({
72+
apolloServer,
73+
extendMockRequest: {
74+
headers: {
75+
cookie: 'csrf=blablabla',
76+
referer: ''
77+
}
78+
}
79+
});
80+
```
81+
82+
This is useful when your apollo server `context` option is a callback that operates on the passed in `req` key, and you want to inject data into that `req` object.
83+
84+
As mentioned above, if you don't pass an `extendMockRequest` to `createTestClient`, we provide a default request mock object for you.
85+
86+
### setOptions
87+
88+
You can also set the `request` mocking option **after** the creation of the `test client`, which is a **cleaner** and **faster** way due not needing to create a new instance for **any** change you might want to do the `request`.
89+
90+
```js
91+
const { query, setOptions } = createTestClient({
92+
apolloServer
93+
});
94+
95+
setOptions({
96+
// If "request" is not specified, it's not modified
97+
request: {
98+
headers: {
99+
cookie: 'csrf=blablabla',
100+
referer: ''
101+
}
102+
}
103+
});
104+
```
105+
106+
## Why not use `apollo-server-testing`?
107+
108+
You can't really write _real_ integration tests with `apollo-server-testing`, because it doesn't support servers which rely on the `context` option being a function that uses the `req` object ([see this issue for more information](https://github.com/apollographql/apollo-server/issues/2277)).
109+
110+
[Real apollo-servers support this behavior](https://www.apollographql.com/docs/apollo-server/essentials/data/#context-argument), but the test client created with `apollo-server-testing` does not. For example:
111+
112+
```js
113+
import { createTestClient } from 'apollo-server-testing';
114+
115+
it('will not work', () => {
116+
const { query } = createTestClient(
117+
new ApolloServer({
118+
schema,
119+
context: ({ req }) => {
120+
return doSomethingWithReq(req); // this won't work because `req` is `undefined`.
121+
}
122+
})
123+
);
124+
125+
// Any middleware or resolver code that depends on `context` will not work when this runs, because
126+
// the `context` function does *not* get passed `req` as expected.
127+
const result = await query({
128+
query: `{ currentUser { id } }`
129+
})
130+
});
131+
```
132+
133+
[The official integration example code from Apollo](https://github.com/apollographql/fullstack-tutorial/blob/6988f6948668ccc2dea3f7a216dd44bdf25a0b9f/final/server/src/__tests__/integration.js#L68-L74) solves this by instantiating an ApolloServer inside the test, mocking the `context` value by hand. But this is not a real integration testing, since you're skipping the whole HTTP framework handling.
134+
135+
## Support
136+
137+
This package should work for consumers using `apollo-server-fastify`.
138+
139+
## Release
140+
141+
To issue a new release run `yarn release`.
142+
143+
## Acknowledgments
144+
145+
This project is inspired by <https://github.com/zapier/apollo-server-integration-testing>.

0 commit comments

Comments
 (0)