Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Allow MockedResponse results to be returned from a function #2788

Merged
merged 2 commits into from
Feb 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. <br/>
[@hwillson](https://github.com/hwillson) in [#2788](https://github.com/apollographql/react-apollo/pull/2788)

## 2.4.1

### Improvements
Expand Down
16 changes: 12 additions & 4 deletions src/test-links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import { print } from 'graphql/language/printer';
import { addTypenameToDocument } from 'apollo-utilities';
const isEqual = require('lodash.isequal');

type ResultFunction<T> = () => T;

export interface MockedResponse {
request: GraphQLRequest;
result?: FetchResult;
result?: FetchResult | ResultFunction<FetchResult>;
error?: Error;
delay?: number;
newData?: () => FetchResult;
newData?: ResultFunction<FetchResult>;
}

export interface MockedSubscriptionResult {
Expand Down Expand Up @@ -86,12 +88,18 @@ export class MockLink extends ApolloLink {
throw new Error(`Mocked response should contain either result or error: ${key}`);
}

return new Observable<FetchResult>(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<FetchResult>)()
: result
);
}
observer.complete();
}
}, delay ? delay : 0);
Expand Down
64 changes: 64 additions & 0 deletions test/test-utils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ChildProps<Variables, Data, Variables>> {
componentWillReceiveProps(nextProps: ChildProps<Variables, Data, Variables>) {
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(
<MockedProvider mocks={testMocks}>
<ContainerWithData {...testVariables} />
</MockedProvider>,
);
});