web-dev-qa-db-ja.com

酵素で「変更」をシミュレートした後、チェックボックスが「チェック」されない

酵素を使用してチェックボックスのchangeイベントをシミュレートし、_chai-enzyme_を使用してチェックされているかどうかをアサートしようとしました。

これは私のHello反応コンポーネントです:

_import React from 'react';

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

  render() {
    const {checked} = this.state;
    return <div>
      <input type="checkbox" defaultChecked={checked} onChange={this._toggle.bind(this)}/>
      {
        checked ? "checked" : "not checked"
      }
    </div>
  }

  _toggle() {
    const {onToggle} = this.props;
    this.setState({checked: !this.state.checked});
    onToggle();
  }
}

export default Hello;
_

そして私のテスト:

_import React from "react";
import Hello from "../src/hello.jsx";
import chai from "chai";
import {mount} from "enzyme";
import chaiEnzyme from "chai-enzyme";
import jsdomGlobal from "jsdom-global";
import spies  from 'chai-spies';

function myAwesomeDebug(wrapper) {
  let html = wrapper.html();
  console.log(html);
  return html
}

jsdomGlobal();
chai.should();
chai.use(spies);
chai.use(chaiEnzyme(myAwesomeDebug));


describe('<Hello />', () => {

  it('checks the checkbox', () => {
    const onToggle = chai.spy();
    const wrapper = mount(<Hello onToggle={onToggle}/>);

    var checkbox = wrapper.find('input');
    checkbox.should.not.be.checked();
    checkbox.simulate('change', {target: {checked: true}});
    onToggle.should.have.been.called.once();

    console.log(checkbox.get(0).checked);
    checkbox.should.be.checked();
  });

});
_

このテストを実行すると、checkbox.get(0).checkedfalseになり、アサーションcheckbox.should.be.checked()はエラーを報告します。

_AssertionError: expected the node in <Hello /> to be checked <input type="checkbox" checked="checked">
_

出力にはすでに_checked="checked"_が含まれているため、メッセージがかなり奇妙であることがわかります。

どこが間違っているのかはわかりません。

ここでもデモプロジェクトを見ることができます: https://github.com/js-demos/react-enzyme-simulate-checkbox-events-demo 、通知 これらの行

15
Freewind

私の説明の詳細の一部は少し間違っているかもしれませんが、私の理解は次のとおりです。

あなたがするとき

_var checkbox = wrapper.find('input');
_

そのEnzymeノードへの参照はcheckboxに保存されますが、酵素ツリーが更新されてもcheckboxは更新されない場合があります。ツリー内の参照が変更されたため、checkboxが古いバージョンのツリー内のノードへの参照になっているためかどうかはわかりません。

checkboxを関数にすると、機能するように見えます。これは、checkbox()の値が常に最新のツリーから取得されるためです。

_var checkbox = () => wrapper.find('input');
checkbox().should.not.be.checked();
checkbox().simulate('change', {target: {checked: true}});
///...
_
14
rogeliog

バグではありませんが、「設計どおりに機能します」。

基礎となる酵素は、反応テストユーティリティを使用して、特にSimulate APIと反応します。

Simulateは実際にはdomを更新しません。コンポーネントに接続されているリアクションイベントハンドラーをトリガーするだけで、おそらく追加のパラメーターを渡します。

私がここで得た答えによると( https://github.com/facebook/react/issues/495 )これは、domを更新するにはReact to多くのブラウザー機能を再実装し、おそらくまだ予期しない動作が発生する可能性があるため、単にブラウザーに依存して更新を行うことにしました。

これを実際にテストする唯一の方法は、手動でdomを手動で更新してから、シミュレートAPIを呼び出すことです。

6
mastrolindus