diff --git a/Changelog.md b/Changelog.md
index 97b968b2fd..088c90c2c9 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -6,6 +6,13 @@
### Improvements
+- A function can now be set as a `MockedResponse` `result` when using
+ `MockedProvider`, such that every time the mocked result is returned,
+ the function is run to calculate the result. This opens up new testing
+ possibilities, like being able to verify if a mocked result was actually
+ requested and received by a test.
+ [@hwillson](https://github.com/hwillson) in [#2788](https://github.com/apollographql/react-apollo/pull/2788)
+
## 2.4.1
### Improvements
diff --git a/src/test-links.ts b/src/test-links.ts
index 8e39fd97ce..9195a7add5 100644
--- a/src/test-links.ts
+++ b/src/test-links.ts
@@ -11,12 +11,14 @@ import { print } from 'graphql/language/printer';
import { addTypenameToDocument } from 'apollo-utilities';
const isEqual = require('lodash.isequal');
+type ResultFunction = () => T;
+
export interface MockedResponse {
request: GraphQLRequest;
- result?: FetchResult;
+ result?: FetchResult | ResultFunction;
error?: Error;
delay?: number;
- newData?: () => FetchResult;
+ newData?: ResultFunction;
}
export interface MockedSubscriptionResult {
@@ -86,12 +88,18 @@ export class MockLink extends ApolloLink {
throw new Error(`Mocked response should contain either result or error: ${key}`);
}
- return new Observable(observer => {
+ return new Observable(observer => {
let timer = setTimeout(() => {
if (error) {
observer.error(error);
} else {
- if (result) observer.next(result);
+ if (result) {
+ observer.next(
+ typeof result === 'function'
+ ? (result as ResultFunction)()
+ : result
+ );
+ }
observer.complete();
}
}, delay ? delay : 0);
diff --git a/test/test-utils.test.tsx b/test/test-utils.test.tsx
index ad3be3d2c2..3dbc9585c5 100644
--- a/test/test-utils.test.tsx
+++ b/test/test-utils.test.tsx
@@ -349,3 +349,67 @@ it('doesnt crash on unmount if there is no query manager', () => {
)
.unmount();
});
+
+it('should support returning mocked results from a function', done => {
+ let resultReturned = false;
+
+ const testUser = {
+ __typename: 'User',
+ id: 12345,
+ };
+
+ class Container extends React.Component> {
+ componentWillReceiveProps(nextProps: ChildProps) {
+ try {
+ expect(nextProps.data!.user).toEqual(testUser);
+ expect(resultReturned).toBe(true);
+ done();
+ } catch (e) {
+ done.fail(e);
+ }
+ }
+
+ render() {
+ return null;
+ }
+ }
+
+ const ContainerWithData = withUser(Container);
+
+ const testQuery: DocumentNode = gql`
+ query GetUser($username: String!) {
+ user(username: $username) {
+ id
+ }
+ }
+ `;
+
+ const testVariables = {
+ username: 'jsmith',
+ };
+ const testMocks = [
+ {
+ request: {
+ query: testQuery,
+ variables: testVariables,
+ },
+ result() {
+ resultReturned = true;
+ return {
+ data: {
+ user: {
+ __typename: 'User',
+ id: 12345,
+ },
+ },
+ };
+ },
+ },
+ ];
+
+ renderer.create(
+
+
+ ,
+ );
+});