gpt4 book ai didi

reactjs - Apollo 的 MockedProvider 没有明确警告丢失的模拟

转载 作者:行者123 更新时间:2023-12-03 18:20:53 25 4
gpt4 key购买 nike

我正在使用 apollo 钩子(Hook)( useQueryuseMutation )对 React 组件进行单元测试,并且在测试中我使用 apollo 的 MockedProvider 模拟实际查询.问题是有时,我的模拟与组件实际发出的查询不匹配(创建模拟时的拼写错误,或者组件演变并更改了一些查询变量)。发生这种情况时,MockedProvided返回一个 NetworkError 给组件。但是在测试套件中,不会显示任何警告。这很令人沮丧,因为有时我的组件对 useQuery 返回的错误没有任何作用。 .这导致我以前通过的测试突然无声无息地失败,让我很难找到原因。

这是使用 useQuery 的组件示例:

import React from 'react';
import {gql} from 'apollo-boost';
import {useQuery} from '@apollo/react-hooks';


export const gqlArticle = gql`
query Article($id: ID){
article(id: $id){
title
content
}
}
`;


export function MyArticleComponent(props) {

const {data} = useQuery(gqlArticle, {
variables: {
id: 5
}
});

if (data) {
return (
<div className="article">
<h1>{data.article.title}</h1>
<p>{data.article.content}</p>
</div>
);
} else {
return null;
}
}

这是一个单元测试,我犯了一个错误,因为模拟的变量对象是 {id: 6}而不是 {id: 5}这将由组件请求。

  it('the missing mock fails silently, which makes it hard to debug', async () => {
let gqlMocks = [{
request:{
query: gqlArticle,
variables: {
/* Here, the component calls with {"id": 5}, so the mock won't work */
"id": 6,
}
},
result: {
"data": {
"article": {
"title": "This is an article",
"content": "It talks about many things",
"__typename": "Article"
}
}
}
}];

const {container, findByText} = render(
<MockedProvider mocks={gqlMocks}>
<MyArticleComponent />
</MockedProvider>
);

/*
* The test will fail here, because the mock doesn't match the request made by MyArticleComponent, which
* in turns renders nothing. However, no explicit warning or error is displayed by default on the console,
* which makes it hard to debug
*/
let titleElement = await findByText("This is an article");
expect(titleElement).toBeDefined();
});

如何在控制台中显示明确的警告?

最佳答案

我已提交 Github issue给 Apollo 团队,以便提出一种内置的方法来做到这一点。同时,这是我自制的解决方案。
这个想法是给 MockedProvider自定义 Apollo 链接。默认情况下,它使用 MockLink用给定的模拟初始化。取而代之的是,我创建了一个自定义链接,它是由 MockLink 组成的链。我以相同的方式创建 MockedProvider会成功,然后是一个 apollo 错误链接,它拦截请求可能返回的错误,并将它们记录在控制台中。为此,我创建了一个自定义提供程序 MyMockedProvider .

MyMockedProvider.js

import React from 'react';
import {MockedProvider} from '@apollo/react-testing';
import {MockLink} from '@apollo/react-testing';
import {onError} from "apollo-link-error";
import {ApolloLink} from 'apollo-link';

export function MyMockedProvider(props) {
let {mocks, ...otherProps} = props;

let mockLink = new MockLink(mocks);
let errorLoggingLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);

if (networkError) console.log(`[Network error]: ${networkError}`);
});
let link = ApolloLink.from([errorLoggingLink, mockLink]);

return <MockedProvider {...otherProps} link={link} />;
}

MyArticleComponent.test.js

import React from 'react';
import {render, cleanup} from '@testing-library/react';

import {MyMockedProvider} from './MyMockedProvider';
import {MyArticleComponent, gqlArticle} from './MyArticleComponent';

afterEach(cleanup);

it('logs MockedProvider warning about the missing mock to the console', async () => {
let gqlMocks = [{
request:{
query: gqlArticle,
variables: {
/* Here, the component calls with {"id": 5}, so the mock won't work */
"id": 6,
}
},
result: {
"data": {
"article": {
"title": "This is an article",
"content": "It talks about many things",
"__typename": "Article"
}
}
}
}];

let consoleLogSpy = jest.spyOn(console, 'log');

const {container, findByText} = render(
<MyMockedProvider mocks={gqlMocks}>
<MyArticleComponent />
</MyMockedProvider>
);

let expectedConsoleLog = '[Network error]: Error: No more mocked responses for the query: query Article($id: ID) {\n' +
' article(id: $id) {\n' +
' title\n' +
' content\n' +
' __typename\n' +
' }\n' +
'}\n' +
', variables: {"id":5}';


await findByText('{"loading":false}');
expect(consoleLogSpy.mock.calls[0][0]).toEqual(expectedConsoleLog);
});

关于reactjs - Apollo 的 MockedProvider 没有明确警告丢失的模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60100062/

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