gpt4 book ai didi

javascript - Apollo MockedProvider 总是返回未定义的数据字段,即使在加载之后

转载 作者:行者123 更新时间:2023-12-05 00:33:07 25 4
gpt4 key购买 nike

一些背景知识:我有一个在加载时立即调用 useQuery 钩子(Hook)的组件。在该查询运行时,我旋转了一个加载微调器。完成后,我会根据数据渲染内容。
我添加了 useEffect监视查询结果并记录数据的钩子(Hook),这就是我观察到这个问题的方式。
为了简化事情,它的工作原理是这样的:

export default function MyComponent(props: ???) {
const result = useQuery(INITIAL_DATA_QUERY, { variables: { id: 1 } });

React.useEffect(() => console.log(JSON.stringify({
loading: result.loading,
data: result.data,
error: result.error,
})), [result]);

if (result.loading) return <LoadingScreen message="Fetching data..."/>;
else if (result.error) return <ErrorPage/>
else return <Stuff info={result.data}> // omitted because it's unimportant to the issue
}
当我在野外运行这个组件时,一切都按预期工作。它通过 Apollo 使用 GraphQL 到达端点,根据结果做出渲染决策等。
但是,当我尝试模拟请求时, result.dataresult.error字段永远不会改变,即使 result.loading领域。我正在使用 react-testing-library运行测试。
我的测试如下所示:
it("should load the data then render the page", () => {

const mocks = [{
request: {
query: INITIAL_DATA_QUERY,
variables: { id: 1 },
},
newData: jest.fn(() => ({
data: {
firstName: "Joe",
lastName: "Random",
}
}))
}];

const mockSpy = mocks[0].newData;

render(
<MockedProvider mocks={mocks} addTypename={false}>
<MyComponent/>
</MockedProvider>
)

// Is it a loading view
expect(result.asFragment()).toMatchSnapshot(); // Passes just fine, and matches expectations

// Wait until the mock has been called once
await waitFor(() => expect(mockSpy).toHaveBeenCalled(1)) // Also passes, meaning the mock was called

// Has the page rendered once the loading mock has finished
expect(result.asFragment()).toMatchSnapshot(); // Passes, but the page has rendered without any of the data
})
问题是这样的:当我运行这个测试时,所有三个测试都按预期通过,但在最终片段中,我渲染的组件中的数据丢失了。我确定正在调用模拟,因为我添加了一些记录器语句来检查。
真正令人困惑的部分是 loading , data , 和 error调用模拟的值。我有一个 useEffect当它们中的任何一个发生变化时记录它们的值的语句,当我运行测试时,输出如下所示:
{ loading: true, data: undefined, error: undefined }
{ loading: false, data: undefined, error: undefined }
这意味着正在调用钩子(Hook)并开始加载,但是一旦加载结束,加载过程中发生的任何事情都不会返回任何数据,也不会产生任何错误。
有人知道我的问题可能是什么吗?我已经看了八种方式到星期天,但无法弄清楚。

最佳答案

我使用 result 模拟了结果 field 。

the result field can be a function that returns a mocked response after performing arbitrary logic


这对我来说可以。 MyComponent.test.tsx :
import { gql, useQuery } from '@apollo/client';
import { useEffect } from 'react';

export const INITIAL_DATA_QUERY = gql`
query GetUser($id: ID!) {
user(id: $id) {
firstName
lastName
}
}
`;

export default function MyComponent(props) {
const result = useQuery(INITIAL_DATA_QUERY, { variables: { id: 1 } });

useEffect(
() =>
console.log(
JSON.stringify({
loading: result.loading,
data: result.data,
error: result.error,
}),
),
[result],
);

if (result.loading) return <p>Fetching data...</p>;
else if (result.error) return <p>{result.error}</p>;
else return <p>{result.data.user.firstName}</p>;
}
MyComponent.test.tsx :
import { render, waitFor } from '@testing-library/react';
import MyComponent, { INITIAL_DATA_QUERY } from './MyComponent';
import { MockedProvider } from '@apollo/client/testing';

describe('68732957', () => {
it('should load the data then render the page', async () => {
const mocks = [
{
request: {
query: INITIAL_DATA_QUERY,
variables: { id: 1 },
},
result: jest.fn().mockReturnValue({
data: {
user: {
lastName: 'Random',
firstName: 'Joe',
},
},
}),
},
];

const mockSpy = mocks[0].result;
const result = render(
<MockedProvider mocks={mocks} addTypename={false}>
<MyComponent />
</MockedProvider>,
);

expect(result.asFragment()).toMatchSnapshot();
await waitFor(() => expect(mockSpy).toBeCalledTimes(1));
expect(result.asFragment()).toMatchSnapshot();
});
});
测试结果:
 PASS  src/stackoverflow/68732957/MyComponent.test.tsx
68732957
✓ should load the data then render the page (58 ms)

console.log
{"loading":true}

at src/stackoverflow/68732957/MyComponent.tsx:18:15

console.log
{"loading":false,"data":{"user":{"firstName":"Joe","lastName":"Random"}}}

at src/stackoverflow/68732957/MyComponent.tsx:18:15

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 2 passed, 2 total
Time: 0.736 s, estimated 1 s
MyComponent.test.tsx.snap :
// Jest Snapshot v1

exports[`68732957 should load the data then render the page 1`] = `
<DocumentFragment>
<p>
Fetching data...
</p>
</DocumentFragment>
`;

exports[`68732957 should load the data then render the page 2`] = `
<DocumentFragment>
<p>
Joe
</p>
</DocumentFragment>
`;
包版本:
"@testing-library/react": "^11.1.0",
"react": "^17.0.1",
"@apollo/client": "^3.4.7",
"graphql": "^15.4.0"

关于javascript - Apollo MockedProvider 总是返回未定义的数据字段,即使在加载之后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68732957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com