Javascript 为什么酶';s`find()`不正确地返回不带';不存在?

Javascript 为什么酶';s`find()`不正确地返回不带';不存在?,javascript,reactjs,jestjs,enzyme,Javascript,Reactjs,Jestjs,Enzyme,下面我有一个示例React组件,其行为如下- 当showDiv状态为false(初始状态)时,它不呈现任何内容 当showDiv状态更新为true(可能是通过某些外部组件、redux等…)时,它通过单个无线电输入呈现 我还包括了笑话测试: import { expect } from 'chai'; import { mount } from 'enzyme'; import PropTypes from 'prop-types'; import React from 'react'; c

下面我有一个示例React组件,其行为如下-

  • showDiv
    状态为
    false
    (初始状态)时,它不呈现任何内容
  • showDiv
    状态更新为
    true
    (可能是通过某些外部组件、redux等…)时,它通过单个无线电输入呈现
我还包括了笑话测试:

import { expect } from 'chai';
import { mount } from 'enzyme';
import PropTypes from 'prop-types';
import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { showDiv: false };
  }

  render() {
    const { showDiv } = this.state;

    if (!showDiv) { return null; }

    return (
      <div className='my-component'>
        <input type="radio" value="yes" id="foo" checked={true} />
      </div>
    );
  }
}


describe('<MyComponent />', () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<MyComponent />);
  });

  it('should render the div', () => {
    // This INCORRECTLY passes
    expect(wrapper.find('#foo').at(0)).to.not.be.null;
    expect(wrapper.find('#foo').at(0)).to.be.checked;
  });
});


有什么原因会导致误报吗?具体来说,为什么
find()
返回不存在但仍通过检查的元素(例如
.to.be.checked

我个人从未使用过
chai
,但它可能需要一些额外的设置来进行React-to-work(我知道jest with-enzyme需要设置)。同样的,我个人建议只使用柴,因为它已经被酶包裹了。。。但最终取决于您使用哪个测试套件

旁注:jest的一个流行插件是,它有like
toExist()
toBeChecked()

使用Jest工作演示(从
浏览器
选项卡切换到
测试
选项卡以运行断言):


App.test.js

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import MyComponent from "./App";

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

describe("<MyComponent />", () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<MyComponent />);
  });

  it("initially displays a button", () => {
    expect(wrapper.find("#show-radio")).toHaveLength(1);
  });

  it("renders the 'my-component' div", () => {
    wrapper.find("#show-radio").simulate("click");

    expect(wrapper.find(".my-component")).toHaveLength(1);
    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("selects a radio", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeTruthy();
  });

  it("resets radio value", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.find("#reset").simulate("click");

    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("hides radios", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#close-radio").simulate("click");

    wrapper.update();

    expect(wrapper.find("#show-radio")).toHaveLength(1);
    expect(wrapper.find(".my-component")).toHaveLength(0);
  });
});
import React from "react";
import "./styles.css";

export default class MyComponent extends React.Component {
  state = { showDiv: false, value: 0 };

  setValue = ({ target: { value } }) => this.setState({ value });

  resetValue = () => this.setState({ value: 0 });

  toggleRadio = () =>
    this.setState((prevState) => ({ showDiv: !prevState.showDiv }));

  render() {
    const { showDiv, value } = this.state;

    if (!showDiv) {
      return (
        <button id="show-radio" type="button" onClick={this.toggleRadio}>
          Toggle
        </button>
      );
    }

    return (
      <div className="my-component">
        <label htmlFor="foo">
          <input
            type="radio"
            id="foo"
            value="1"
            checked={value === "1"}
            onChange={this.setValue}
          />
          1
        </label>
        <label htmlFor="bar">
          <input
            type="radio"
            id="bar"
            value="2"
            checked={value === "2"}
            onChange={this.setValue}
          />
          2
        </label>
        <br />
        <button id="reset" type="button" onClick={this.resetValue}>
          Reset
        </button>
        <button id="close-radio" type="button" onClick={this.toggleRadio}>
          Close
        </button>
      </div>
    );
  }
}
从“React”导入React;
从“酶”导入{configure,mount};
从“酶-适配器-反应-16”导入适配器;
从“/App”导入MyComponent;
配置({adapter:newadapter()});
描述(“,()=>{
让包装纸;
在每个之前(()=>{
包装器=mount();
});
它(“最初显示一个按钮”,()=>{
expect(wrapper.find(“#show radio”).toHaveLength(1);
});
它(“呈现‘我的组件’div)”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
expect(wrapper.find(“.my component”).toHaveLength(1);
expect(wrapper.find(“#foo”).props();
});
它(“选择收音机”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
find(“#foo”).prop(“onChange”)({target:{value:{1}});
wrapper.update();
expect(wrapper.find(“#foo”).props();
});
它(“重置无线电值”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
find(“#foo”).prop(“onChange”)({target:{value:{1}});
包装器。查找(“重置”)。模拟(“单击”);
wrapper.update();
expect(wrapper.find(“#foo”).props();
});
它(“隐藏收音机”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
包装器。查找(“关闭收音机”)。模拟(“单击”);
wrapper.update();
expect(wrapper.find(“#show radio”).toHaveLength(1);
expect(wrapper.find(“.my component”).toHaveLength(0);
});
});
App.js

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import MyComponent from "./App";

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

describe("<MyComponent />", () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<MyComponent />);
  });

  it("initially displays a button", () => {
    expect(wrapper.find("#show-radio")).toHaveLength(1);
  });

  it("renders the 'my-component' div", () => {
    wrapper.find("#show-radio").simulate("click");

    expect(wrapper.find(".my-component")).toHaveLength(1);
    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("selects a radio", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeTruthy();
  });

  it("resets radio value", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.find("#reset").simulate("click");

    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("hides radios", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#close-radio").simulate("click");

    wrapper.update();

    expect(wrapper.find("#show-radio")).toHaveLength(1);
    expect(wrapper.find(".my-component")).toHaveLength(0);
  });
});
import React from "react";
import "./styles.css";

export default class MyComponent extends React.Component {
  state = { showDiv: false, value: 0 };

  setValue = ({ target: { value } }) => this.setState({ value });

  resetValue = () => this.setState({ value: 0 });

  toggleRadio = () =>
    this.setState((prevState) => ({ showDiv: !prevState.showDiv }));

  render() {
    const { showDiv, value } = this.state;

    if (!showDiv) {
      return (
        <button id="show-radio" type="button" onClick={this.toggleRadio}>
          Toggle
        </button>
      );
    }

    return (
      <div className="my-component">
        <label htmlFor="foo">
          <input
            type="radio"
            id="foo"
            value="1"
            checked={value === "1"}
            onChange={this.setValue}
          />
          1
        </label>
        <label htmlFor="bar">
          <input
            type="radio"
            id="bar"
            value="2"
            checked={value === "2"}
            onChange={this.setValue}
          />
          2
        </label>
        <br />
        <button id="reset" type="button" onClick={this.resetValue}>
          Reset
        </button>
        <button id="close-radio" type="button" onClick={this.toggleRadio}>
          Close
        </button>
      </div>
    );
  }
}
从“React”导入React;
导入“/styles.css”;
导出默认类MyComponent扩展React.Component{
状态={showDiv:false,值:0};
setValue=({target:{value}})=>this.setState({value});
resetValue=()=>this.setState({value:0});
切换收音机=()=>
this.setState((prevState)=>({showDiv:!prevState.showDiv}));
render(){
const{showDiv,value}=this.state;
如果(!showDiv){
返回(
切换
);
}
返回(
1.
2.

重置 接近 ); } }
我个人从未使用过
chai
,但它可能需要一些额外的设置来进行React to work(我知道与酶开玩笑需要一个)。同样的,我个人建议只使用柴,因为它已经被酶包裹了。。。但最终取决于您使用哪个测试套件

旁注:jest的一个流行插件是,它有like
toExist()
toBeChecked()

使用Jest工作演示(从
浏览器
选项卡切换到
测试
选项卡以运行断言):


App.test.js

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import MyComponent from "./App";

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

describe("<MyComponent />", () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<MyComponent />);
  });

  it("initially displays a button", () => {
    expect(wrapper.find("#show-radio")).toHaveLength(1);
  });

  it("renders the 'my-component' div", () => {
    wrapper.find("#show-radio").simulate("click");

    expect(wrapper.find(".my-component")).toHaveLength(1);
    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("selects a radio", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeTruthy();
  });

  it("resets radio value", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.find("#reset").simulate("click");

    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("hides radios", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#close-radio").simulate("click");

    wrapper.update();

    expect(wrapper.find("#show-radio")).toHaveLength(1);
    expect(wrapper.find(".my-component")).toHaveLength(0);
  });
});
import React from "react";
import "./styles.css";

export default class MyComponent extends React.Component {
  state = { showDiv: false, value: 0 };

  setValue = ({ target: { value } }) => this.setState({ value });

  resetValue = () => this.setState({ value: 0 });

  toggleRadio = () =>
    this.setState((prevState) => ({ showDiv: !prevState.showDiv }));

  render() {
    const { showDiv, value } = this.state;

    if (!showDiv) {
      return (
        <button id="show-radio" type="button" onClick={this.toggleRadio}>
          Toggle
        </button>
      );
    }

    return (
      <div className="my-component">
        <label htmlFor="foo">
          <input
            type="radio"
            id="foo"
            value="1"
            checked={value === "1"}
            onChange={this.setValue}
          />
          1
        </label>
        <label htmlFor="bar">
          <input
            type="radio"
            id="bar"
            value="2"
            checked={value === "2"}
            onChange={this.setValue}
          />
          2
        </label>
        <br />
        <button id="reset" type="button" onClick={this.resetValue}>
          Reset
        </button>
        <button id="close-radio" type="button" onClick={this.toggleRadio}>
          Close
        </button>
      </div>
    );
  }
}
从“React”导入React;
从“酶”导入{configure,mount};
从“酶-适配器-反应-16”导入适配器;
从“/App”导入MyComponent;
配置({adapter:newadapter()});
描述(“,()=>{
让包装纸;
在每个之前(()=>{
包装器=mount();
});
它(“最初显示一个按钮”,()=>{
expect(wrapper.find(“#show radio”).toHaveLength(1);
});
它(“呈现‘我的组件’div)”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
expect(wrapper.find(“.my component”).toHaveLength(1);
expect(wrapper.find(“#foo”).props();
});
它(“选择收音机”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
find(“#foo”).prop(“onChange”)({target:{value:{1}});
wrapper.update();
expect(wrapper.find(“#foo”).props();
});
它(“重置无线电值”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
find(“#foo”).prop(“onChange”)({target:{value:{1}});
包装器。查找(“重置”)。模拟(“单击”);
wrapper.update();
expect(wrapper.find(“#foo”).props();
});
它(“隐藏收音机”,()=>{
包装器。查找(#show radio”)。模拟(“单击”);
包装器。查找(“关闭收音机”)。模拟(“单击”);
wrapper.update();
expect(wrapper.find(“#show radio”).toHaveLength(1);
expect(wrapper.find(“.my component”).toHaveLength(0);
});
});
App.js

import React from "react";
import { configure, mount } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import MyComponent from "./App";

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

describe("<MyComponent />", () => {
  let wrapper;

  beforeEach(() => {
    wrapper = mount(<MyComponent />);
  });

  it("initially displays a button", () => {
    expect(wrapper.find("#show-radio")).toHaveLength(1);
  });

  it("renders the 'my-component' div", () => {
    wrapper.find("#show-radio").simulate("click");

    expect(wrapper.find(".my-component")).toHaveLength(1);
    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("selects a radio", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeTruthy();
  });

  it("resets radio value", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#foo").prop("onChange")({ target: { value: "1" } });
    wrapper.find("#reset").simulate("click");

    wrapper.update();

    expect(wrapper.find("#foo").props().checked).toBeFalsy();
  });

  it("hides radios", () => {
    wrapper.find("#show-radio").simulate("click");
    wrapper.find("#close-radio").simulate("click");

    wrapper.update();

    expect(wrapper.find("#show-radio")).toHaveLength(1);
    expect(wrapper.find(".my-component")).toHaveLength(0);
  });
});
import React from "react";
import "./styles.css";

export default class MyComponent extends React.Component {
  state = { showDiv: false, value: 0 };

  setValue = ({ target: { value } }) => this.setState({ value });

  resetValue = () => this.setState({ value: 0 });

  toggleRadio = () =>
    this.setState((prevState) => ({ showDiv: !prevState.showDiv }));

  render() {
    const { showDiv, value } = this.state;

    if (!showDiv) {
      return (
        <button id="show-radio" type="button" onClick={this.toggleRadio}>
          Toggle
        </button>
      );
    }

    return (
      <div className="my-component">
        <label htmlFor="foo">
          <input
            type="radio"
            id="foo"
            value="1"
            checked={value === "1"}
            onChange={this.setValue}
          />
          1
        </label>
        <label htmlFor="bar">
          <input
            type="radio"
            id="bar"
            value="2"
            checked={value === "2"}
            onChange={this.setValue}
          />
          2
        </label>
        <br />
        <button id="reset" type="button" onClick={this.resetValue}>
          Reset
        </button>
        <button id="close-radio" type="button" onClick={this.toggleRadio}>
          Close
        </button>
      </div>
    );
  }
}
从“React”导入React;
导入“/styles.css”;
导出默认类MyComponent扩展React.Component{
状态={showDiv:false,值:0};
setValue=({target:{value}})=>this.setState({value});
resetValue=()=>this.setState({value:0});
切换收音机=()=>
this.setState((prevState)=>({showDiv:!prevState.showDiv}));
render(){
常量{showDiv,value}