使用Jest和快照测试嵌套组件返回null

3

我正在尝试创建类似于Summary.test.jsSelectColumn.test.js

https://gitlab.com/sosy-lab/software/benchexec/-/blob/SelectColumn.test/benchexec/tablegenerator/react-table/src/tests/SelectColumn.test.js

但不幸的是,我的尝试都没有成功,我尝试了来自代码论坛的所有解决方案。但似乎我做错了什么。
结果:失败
期望的结果应该是:通过
错误:
react-modal:找不到选择器#root的任何元素。
      180 | 
      181 |   render() {
    > 182 |     ReactModal.setAppElement("#root");
          |                ^
      183 |     return (
      184 |       <ReactModal
      185 |         className="overlay"

2020年01月03日编辑:

我添加了<div id="root">,解决了错误:

react-modal:未找到选择器#root的任何元素。

但现在出现了新的错误:

TypeError:parentInstance.children.indexOf不是一个函数

代码如下:

      81 |           .create(<Overview data={data} />)
      82 |           .getInstance();
    > 83 |         const component = renderer.create(component_func(overview));
         |                                    ^
      84 | 
      85 |         expect(component).toMatchSnapshot();
      86 |       });

我尝试将ReactModal.setAppElement移动到componentDidMount中,但似乎这不是解决方案。
编辑于04.03.2020:
现在我更改了我的代码,让它从App.js的主组件进行测试,这很好用,但我想仅测试子组件SelectColumn。我尝试使用shallowfind,但快照始终为exports[...] = null;
import React from "react";
import SelectColumn from "../App.js";
import { test_snapshot_of } from "./utils.js";
import Enzyme, { shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";

Enzyme.configure({ adapter: new Adapter() });

// mock uniqid to have consistent names
// https://stackoverflow.com/a/44538270/396730
jest.mock("uniqid", () => i => i + "uniqid");

const wrapper = shallow(<SelectColumn />);
const rootElement = wrapper.find("#root");
test_snapshot_of("Render SelectColumn", overview => rootElement);
4个回答

1

看起来 #root 不是 SelectColumn 中的一个元素?但是在你的测试用例中,你只是导入了 SelectColumn 并想进行快照比较?所以我认为在这种情况下 React-Modal 无法正确工作,因为它无法在此测试范围内找到 #root 元素。我认为 Jest 不会为此测试创建 SelectColumn 外部的虚拟 Dom。

首先,我认为你可以尝试将<div id="root">作为最外层元素包装在SelectColumn组件中,以验证问题是否与我所想的一样。如果成功了,那么你可能应该考虑将这个根元素添加到这个组件中,这也使得这个组件更具可重用性和解耦性(另外我也试图找到#root这里, 但我也找不到它,它是在更外部的组件中吗?)

很遗憾,这对我不起作用:react-modal: 未找到选择器#root的元素。 22 | 23 | componentDidMount() {` > 24 | ReactModal.setAppElement("#root"); | ^ 25 | } 26 | // -------------------------Rendering------------------------- 27 | renderRunSets = () => { - Martin
1
@Martin,抱歉我粗心了,这应该是运行测试的问题,已经更新了答案,希望有所帮助! - Carr
谢谢,这个错误似乎已经被解决了,但现在它又出现另外一个错误:TypeError: parentInstance.children.indexOf is not a function,位于第83行:const component = renderer.create(component_func(overview)); - Martin
1
@Martin,这个错误也出现在测试中吗?你创建了一个ID为#root的元素吗?如果是的话,也许你可以尝试将ReactModal.setAppElement移动到componentDidMount中,实际上最好是创建另一个问题并提供更多信息 :) - Carr

0
在运行测试时,reactModal DOM不可用,因此通过过滤测试用例,它不会将#root元素设置为null。
if (process.env.NODE_ENV !== 'test') ReactModal.setAppElement('#root');

请不要仅仅发布代码作为答案,还需要提供解释您的代码是如何解决问题的。带有解释的答案通常更有帮助和更高质量,并且更有可能获得赞同。 - Mark Rotteveel
我认为代码非常自解释。也许我错了。我将在回复中添加一些注释。 - snowyBunny

0
与其为了测试而删除模态框,建议的解决方案是将setAppElement调用移出项目的测试范围。我曾在“Modal”包装组件中调用它,但现在我将其移到我的入口App.js文件中(这个文件在测试中实际上并不运行)。

如果你真的需要测试它,可以这样做:

ReactModal.setAppElement(document.createElement('div'));
describe("test component that uses modal", () => {
   ...
});

0
在我的情况下,ContactForm 是我使用模型的组件。以下代码有助于在测试时消除错误。
describe("test component that uses modal", () => {
  it('renders without crashing', () => {
    render(
      ReactModal.setAppElement(document.createElement('div')),
      <ContactForm> </ContactForm>
    );
  });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接