来自 React 测试库的 fireEvent.scroll 没有在第二次调用时更新 classList
fireEvent.scroll from React Testing Library is not updating classList on second call
我的 React 项目中有一个 class 组件代表我的导航栏。我正在使用 window.scrollY
更新布尔状态 scrolled
.
当用户滚动时,class nav-shadow
应该添加到导航栏 div 的 className
属性。
代码 运行 非常完美,但是当我 运行 将它们全部放在一起时,我的一个测试失败了。
这是我的代码:
AppNav.tsx
class AppNav extends Component<any, {scrolled: boolean}> {
constructor(props: any) {
super(props);
this.state = {
scrolled: false
};
this.onScroll = this.onScroll.bind(this);
}
onScroll() {
const scrollY = window.scrollY;
this.setState({
scrolled: scrollY >= 75
});
}
componentDidMount() {
window.addEventListener("scroll", this.onScroll);
}
render() {
return (
<div aria-label="navigation" className={`${this.state.scrolled ? "nav-shadow" : ""}`}>
<p>Navbar Code...</p>
</div>
);
}
}
export default AppNav;
AppNav.test.tsx
describe("AppNav", () => {
const { getByLabelText } = renderWithRouter(<AppNav/>);
const appNav = getByLabelText(/navigation/i);
// PASS
it("should be in the document", () => {
expect(appNav).toBeInTheDocument();
});
// PASS
it("should not have nav-shadow as class if window scroll is less than 75", () => {
Array.from(Array(74).keys()).forEach(scrollY => {
fireEvent.scroll(window, {
target: {
scrollY
}
});
expect(appNav.classList.contains("nav-shadow")).toBe(false);
});
});
// FAIL
// But PASS if ran individually
it("should have nav-shadow as class if window scroll is more than or equal to 75", () => {
Array.from(Array(100).keys()).map(i => i + 75).forEach(scrollY => {
fireEvent.scroll(window, {
target: {
scrollY
}
});
expect(appNav.classList.contains("nav-shadow")).toBe(true);
});
});
});
通过测试
应用导航
- 应该在文档中
- 如果 window 滚动小于 75
,则导航阴影不应像 class
失败的测试
- 如果 window 滚动大于或等于 75
,则导航阴影应为 class
调试代码,我发现当我 运行 整个测试套件时 nav-shadow
class 没有被添加。但是,当individual 测试是运行 individually.
时正在添加调用
我正在使用 react 测试库和 jest 的 jsdom。
正如您所说,您的测试 运行 单独运行良好,那么最好进行沙盒测试并为 每个 调用 renderWithRouter(<AppNav/>)
和 getByLabelText(/navigation/i)
测试,而不是在所有测试的顶部一次。这将确保您为每个测试重置 js-dom 实例。
查看此沙箱并通过测试:https://codesandbox.io/s/brave-mclean-n0gfs?file=/src/App.test.js(使用 render
而不是 renderWithRouter
但结果应该相同)
我的 React 项目中有一个 class 组件代表我的导航栏。我正在使用 window.scrollY
更新布尔状态 scrolled
.
当用户滚动时,class nav-shadow
应该添加到导航栏 div 的 className
属性。
代码 运行 非常完美,但是当我 运行 将它们全部放在一起时,我的一个测试失败了。
这是我的代码:
AppNav.tsx
class AppNav extends Component<any, {scrolled: boolean}> {
constructor(props: any) {
super(props);
this.state = {
scrolled: false
};
this.onScroll = this.onScroll.bind(this);
}
onScroll() {
const scrollY = window.scrollY;
this.setState({
scrolled: scrollY >= 75
});
}
componentDidMount() {
window.addEventListener("scroll", this.onScroll);
}
render() {
return (
<div aria-label="navigation" className={`${this.state.scrolled ? "nav-shadow" : ""}`}>
<p>Navbar Code...</p>
</div>
);
}
}
export default AppNav;
AppNav.test.tsx
describe("AppNav", () => {
const { getByLabelText } = renderWithRouter(<AppNav/>);
const appNav = getByLabelText(/navigation/i);
// PASS
it("should be in the document", () => {
expect(appNav).toBeInTheDocument();
});
// PASS
it("should not have nav-shadow as class if window scroll is less than 75", () => {
Array.from(Array(74).keys()).forEach(scrollY => {
fireEvent.scroll(window, {
target: {
scrollY
}
});
expect(appNav.classList.contains("nav-shadow")).toBe(false);
});
});
// FAIL
// But PASS if ran individually
it("should have nav-shadow as class if window scroll is more than or equal to 75", () => {
Array.from(Array(100).keys()).map(i => i + 75).forEach(scrollY => {
fireEvent.scroll(window, {
target: {
scrollY
}
});
expect(appNav.classList.contains("nav-shadow")).toBe(true);
});
});
});
通过测试
应用导航
- 应该在文档中
- 如果 window 滚动小于 75 ,则导航阴影不应像 class
失败的测试
- 如果 window 滚动大于或等于 75 ,则导航阴影应为 class
调试代码,我发现当我 运行 整个测试套件时 nav-shadow
class 没有被添加。但是,当individual 测试是运行 individually.
我正在使用 react 测试库和 jest 的 jsdom。
正如您所说,您的测试 运行 单独运行良好,那么最好进行沙盒测试并为 每个 调用 renderWithRouter(<AppNav/>)
和 getByLabelText(/navigation/i)
测试,而不是在所有测试的顶部一次。这将确保您为每个测试重置 js-dom 实例。
查看此沙箱并通过测试:https://codesandbox.io/s/brave-mclean-n0gfs?file=/src/App.test.js(使用 render
而不是 renderWithRouter
但结果应该相同)