我正在尝试使用Jest和react-testing-library模拟和测试在React中使用ApolloClient完成的API调用。但是看来通话从未发生。
代码分布在同一/ src目录中的三个文件中:
/src/apolloClient.js保存了一个客户端实例:
import ApolloClient from "apollo-boost";
export const client = new ApolloClient({
uri: "https://api.github.com/graphql",
headers: {
authorization: `Bearer ${process.env.REACT_APP_GITHUB_ACCESS_TOKEN}`
}
});
query.js包含graphql查询和进行调用的函数:
import { gql } from "apollo-boost";
import { client } from "../apolloClient";
export const userQuery = gql`
query($login: String!) {
user(login: $login) {
name
email
...
}
}
`;
export const getGitHubProfile = (userLogin, setUser) =>
client
.query({ query: userQuery, variables: { login: userLogin } })
.then(response => setUser(response.data.user))
.catch(err => console.log(err));
Landing.js包含进行调用的表单:
import React, { useState } from "react";
import { getGitHubProfile } from "./query";
import CV from "./CV";
function Landing() {
const [userLogin, setUserLogin] = useState("");
const [user, setUser] = useState();
const submitUserLogin = async e => {
e.preventDefault();
userLogin && getGitHubProfile(userLogin, setUser); // Called here on submit.
};
const gitHubUsernameForm = () => {
return (
...
<form
data-testid="form"
className="form field has-addons"
onSubmit={submitUserLogin}
>
<div className="control has-icons-left">
<input
className="input"
type="text"
name="github-username"
aria-label="github-username"
placeholder="What's your GitHub username?"
defaultValue="Bobby"
onChange={e => setUserLogin(e.target.value)}
/>
</div>
<div className="control">
<button data-testid="button" className="button">
Submit
</button>
</div>
</form>
...
);
};
return user ? <CV data-testid="CV" user={user} /> : gitHubUsernameForm();
}
export default Landing;
基本上,在Landing.js中单击提交会触发submitUserLogin()
,该getGitHubProfile()
在query.js中运行client
以使用apolloClient.js中的<CV data-testid="CV" user={user} />
向GitHub索要东西。
如果拨打电话,则出现user ? <p data-testid="CV">Testing only</p> : null
。现在还不存在,但是我还尝试过在布局中插入data-testid
,以防npm start
在组件上不起作用(我对测试还不熟悉)。
当我运行import Landing from "../Landing";
import { MockedProvider } from "@apollo/react-testing";
import { userQuery } from "../query";
const mocks = [
{
request: {
query: userQuery,
variables: {
login: "Bobby"
}
},
result: {
data: {
user: { location: "South Woobeewoo" }
}
}
}
];
it("Calls API", async () => {
const { getByLabelText, getByText, getByTestId } = render(
<MockedProvider mocks={mocks} addTypename={false}>
<Landing />
</MockedProvider>
);
const input = getByLabelText("github-username");
fireEvent.change(input, { target: { value: "Bobby" } });
console.log(input.value); // Shows input is successful.
fireEvent.click(getByText("Submit"));
const response = await waitForElement(() => getByTestId("CV")); // Always fails here.
expect(response).toBeTruthy();
});
时,这在网站本身上效果很好。
但是,我不知道如何测试是否进行了API调用。在阅读了有关Apollo和react-testing-library的文档并尝试了许多方法之后,我认为这是目前最可行的解决方案:
fireEvent.click()
测试始终失败,并显示“无法通过[data-testid =“ CV”]查找元素”。
我知道pressed
之所以有效,是因为我还尝试使此单击事件设置为data-testid="CV"
状态(现已删除)以触发标有cols = df.columns
np.where(cols.str.isdigit(), 'a' + cols, cols)
# array(['a', 'b', 'a0', 'a1', 'a2', 'a3'], dtype=object)
df.columns = np.where(cols.str.isdigit(), 'a' + cols, cols)
df
a b a0 a1 a2 a3
0 x x x x x x
1 x x x x x x
2 x x x x x x
的测试元素的出现。
我已经在Apollo官方文档here中尝试了测试模式,并在表单本身上触发了提交,例如here,也触发了one。还要通读有关触发事件的测试文档here。
我认为我只是在某种程度上没有正确地进行模拟。我在做什么错了?