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( + + + , + ); +});