这是我使用MockedProvider的方式。如何在模拟数组中模拟refetch?
const mocks = [{
request: {
query: GET_USERS_BY_FACILITY,
variables: {
facility: 300
}
},
result: {
data: {
GetUsersByFacility: [{
nuId: 'Q916983',
userName: faker.internet.userName(),
profileKey: 'testKey',
profileValue: 'testValue',
__typename: 'FacilityUser'
}]
}
},
refetch: () => {
return {
data: {
GetUsersByFacility: [{
nuId: 'Q916983',
userName: faker.internet.userName(),
profileKey: 'testKey',
profileValue: 'testValue',
__typename: 'FacilityUser'
}]
}
}
}
}
此测试用例在触发删除事件时调用refetch函数。
it('should be able to click on delete user', async () => {
const {getByTestId} = render(
<MockedProvider mocks={mocks}>
<Users selectedFacility={300}/>
</MockedProvider>)
await wait(0)
fireEvent.click(getByTestId('btnDelete'))
})
我一直在尝试不同的方法,但似乎没有一种起作用。我收到错误消息,为 TypeError:无法读取未定义的属性'refetch'。
非常感谢您的答复。
关于, -拉贾尼
答案 0 :(得分:2)
也许回答有点晚了,但是如果您还没有任何答案,您可以参考我的解决方法。
请注意,这可能不是正确的答案。
const mocks = [
{
request: {
query: GET_DOG_QUERY,
variables: {
name: 'Buck',
},
},
result: () => {
// do something, such as recording that this function has been called
// ...
return {
data: {
dog: { id: '1', name: 'Buck', breed: 'bulldog' },
},
}
},
},
];
// do something, such as recording that this function has been called
这是我的模拟示例。
let queryCalled = false
const testingData = (value) => ({
data: {....}
})
const TESTING_MOCK = {
request: {
query: TESTING_QUERY,
variables: { some: "variables" },
},
result: () => {
if (queryCalled) return testingData("refetched");
else {
queryCalled = true;
return testingData("first fetched");
}
},
};
queryCalled
是false
,因此它将queryCalled
重新分配为true
并返回“第一个提取的”模拟数据,我的测试代码示例在这里
it("refetch when clicked save button.", async () => {
const mocks = [TESTING_MOCK];
let utils: RenderResult = render(<SomeTestingComponent mocks={mocks} />);
await waitForNextTick(); //for getting a data, not loading
const titleInput = utils.getByDisplayValue("first fetched");
const saveBtn = utils.getByText("save");
fireEvent.click(saveBtn);
await waitForElement(() => utils.getByDisplayValue("refetched"));
})
如果您还有其他建议,请告诉我!
答案 1 :(得分:1)
此解决方案对我不起作用,并且不确定是否可以解决,因为在我的情况下不起作用。
let queryCalled = false
const testingData = (value) => ({
data: {....}
})
const TESTING_MOCK = {
request: {
query: TESTING_QUERY,
variables: { some: "variables" },
},
result: () => {
if (queryCalled) return testingData("refetched");
else {
queryCalled = true;
return testingData("first fetched");
}
},
};
所以我用另一种方法解决了它:
const mocks = [
{
request: {
query: GET_DOG_QUERY,
variables: {
name: 'Buck',
},
},
result: {
data: {
dog: { id: '1', name: 'Buck', breed: 'bulldog' },
},
},
newData: jest.fn(() => ({
data: {
dog: { id: '1', name: 'Refetched-Buck', breed: 'refetched-bulldog' },
},
})),
},
];
对我来说,它就像是一种魅力。
答案 2 :(得分:0)
newData
解决方案不适用于apollo客户端@2.6
。
作为一种解决方法,对于一些利用refetch
的测试,我不得不物理模拟useQuery
函数,并提供模拟函数以返回refetch
;对于我们的自定义钩子(将覆盖的useQuery
钩子导出为default
),它看起来像这样:
import * as useQueryModule from '~/hooks/useQuery';
describe('test the thing', () => {
let useQuerySpy;
beforeEach(() => {
// Spy on the `useQuery` function so we can optionally provide alternate behaviour.
useQuerySpy = jest.spyOn(useQueryModule, 'default');
})
afterEach(() => {
// Restore any mocked behaviour
useQuerySpy.mockRestore();
});
it('does a thing', async () => {
const refetchedApolloResponse = buildResponse(refetchData) // some function to build the shape / data of apollo response
const initialApolloResponse = buildResponse(initialData) // some function to build the shape / data of apollo response
const mockRefetch = jest.fn().mockResolvedValue({ data: refetchedApolloResponse });
useQuerySpy.mockReturnValue({ data: initialApolloResponse, refetch: mockRefetch });
// Assert stuff
}
})
答案 3 :(得分:0)
对于可能仍会遇到此问题的任何人,在测试中使refetch起作用的解决方案是使用newData
方法,同时跟踪已被调用的查询。
我不知道这是否是MockedProvider实现中的错误,但是我想让newData
与result
一起工作时碰壁,但事实证明{ {1}}会完全覆盖newData
。
一个可行的解决方案(经过useQuery和Apollo Client 3的测试)将是这样的:
result