我正在使用 react-apollo 构建一个使用 GraphQL API 的客户端,但是,我非常专注于测试。我想要的是模拟服务器,这样我就可以轻松地测试应用程序而无需进行网络调用。
我找到了一些关于如何模拟服务器的指示:
- > https://dev-blog.apollodata.com/mocking-your-server-with-just-one-line-of-code-692feda6e9cd
- > http://dev.apollodata.com/tools/graphql-tools/mocking.html#addMockFunctionsToSchema
但实际上并没有关于如何在我的应用程序测试中使用这个模拟服务器以避免命中服务器的示例。
我的目标是设置集成测试以断言该应用确实在运行:
describe('Profile feature', () => {
beforeAll(() => {
store = setupStore();
app = mount(
<ApolloProvider store={store} client={apolloClient}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</ApolloProvider>
);
});
});
商店使用的是 Redux,客户端是这样创建的:
const networkInterface = createNetworkInterface({
uri: process.env.REACT_APP_API_URL
});
export const apolloClient = new ApolloClient({
networkInterface
});
我如何在这里使用带有 graphql-tools 的模拟服务器而不是实际的 API?
最佳答案
我发现了 2 种不同的方式来为 apollo-client 查询创建模拟数据:
首先是使用graphql-tools根据您的后端模式创建一个模拟服务器,为了将这个模拟服务器与您的测试连接起来,可以像这样创建一个模拟网络接口(interface):
const { mockServer } = require("graphql-tools");
const { print } = require("graphql/language/printer");
class MockNetworkInterface {
constructor(schema, mocks = {}) {
if (schema === undefined) {
throw new Error('Cannot create Mock Api without specifying a schema');
}
this.mockServer = mockServer(schema, mocks);
}
query(request) {
return this.mockServer.query(print(request.query), request.variables);
}
}
您可以将此网络接口(interface)传递给 ApolloClient 组件,它应该可以正常工作!
进行此设置需要在您的客户端中更新您的 API 架构,所以我发现这样做有点麻烦。
另一种方法是使用apollo-client/test-utils
提供的mockNetworkInterface
你可以这样使用它:
import App from './App';
import { UserMock, PublicationMock } from '../__mocks__/data';
import { mockNetworkInterface } from 'react-apollo/test-utils';
import ApolloClient from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
// We will be using here the exact same Query defined in our components
// We will provide a custom result or a custom error
const GraphQLMocks = [
{
request: {
query: UserProfileQuery,
variables: {}
},
result: {
data: {
current_user: UserMock
}
}
}
];
// To set it up we pass the mocks to the mockNetworkInterface
const setupTests = () => {
const networkInterface = mockNetworkInterface.apply(null, GraphQLMocks);
const client = new ApolloClient({ networkInterface, addTypename: false });
const wrapper = mount(
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
return {
store,
wrapper
};
};
// Then the tests look like this
describe('Profile feature', () => {
test('Profile view should render User details', async () => {
const { wrapper, store } = setupTests();
const waitFor = createWaitForElement('.profile');
await waitFor(wrapper);
const tag = wrapper.find('.profile-username');
expect(tag.text()).toEqual(`${UserMock.first_name} ${UserMock.last_name}`);
});
});
将 addTypename: false
传递给 ApolloClient
实例很重要,否则您需要手动将 __typename
添加到所有查询中。
您可以在此处检查 mockNetworkInterface 的实现:https://github.com/apollographql/apollo-test-utils/blob/master/src/mocks/mockNetworkInterface.ts
关于testing - 如何使用带有 react-apollo 的模拟数据进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45700550/