酵素-<input>値にアクセスして設定する方法は?


91

<input>使用するときに値にアクセスする方法について混乱していますmount。これが私のテストとして得たものです:

  it('cancels changes when user presses esc', done => {
    const wrapper = mount(<EditableText defaultValue="Hello" />);
    const input = wrapper.find('input');

    console.log(input.render().attr('value'));
    input.simulate('focus');
    done();
  });

コンソールが印刷されundefinedます。しかし、コードを少し変更すると、機能します。

  it('cancels changes when user presses esc', done => {
    const wrapper = render(<EditableText defaultValue="Hello" />);
    const input = wrapper.find('input');

    console.log(input.val());
    input.simulate('focus');
    done();
  });

もちろん、input.simulate私がrender今使っているので、回線が失敗することを除いて。正しく動作するには両方が必要です。これを修正するにはどうすればよいですか?

編集

言及する必要<EditableText />がありますが、制御されたコンポーネントではありません。私が合格したときにしかしdefaultValue<input />、値を設定しているようです。上記の2番目のコードブロックは値を出力します。同様に、Chromeで入力要素を調べ$0.valueてコンソールに入力すると、期待値が表示されます。

回答:


100

私はあなたが欲しいものは次のとおりだと思います:

input.simulate('change', { target: { value: 'Hello' } })

これが私のソースです。

render()値を設定するためにどこでも使用する必要はありません。参考までに、2つの異なるを使用していますrender()。最初のコードブロックにあるものはEnzymeからのものであり、ラッパーオブジェクトのメソッドでありmountfind提供します。2つ目は、100%明確ではありませんが、おそらくからのものreact-domです。Enzymeを使用している場合は、shallowまたはmount必要に応じて使用するだけで、renderfromは必要ありませんreact-dom


input.render()されていないreact-domレンダリング。それはこれです:airbnb.io/enzyme/docs/api/ShallowWrapper/render.html
ffxsam

3
また、shallow()何らかの理由で機能しません。focusイベントは、参照しようとするメソッドをトリガーしますがthis.refs.input、失敗します。しかし、に交換するshallowmount、期待どおりに機能します。主に..(ESCキーのシミュレーションに関するもう1つの問題)
ffxsam 2016年

もっと明確にすべきだった。私はのように見えるレンダリングを意味しましたrender(<EditableText defaultValue="Hello" />)。あなたのユースケースは私が思っていたよりも専門的だと思います。入力値を設定するだけで、フォーカスと「変更のキャンセル」を扱っているようです。プランカーを作成できれば素晴らしいと思います。
タイラーコリアー2016年

こんにちは、などのデフォルト値で問題が発生しました。で設定されているように期待値は100ですがthis.state = {inputNum: 10};受信は常に1になります。誰か助けてもらえますか?input.simulate('change', { target: { value: '100' } })
nambk

@nambk新しい質問をするのが最善でしょう。おそらく、それはの周りの引用符と関係があります'100'。私は10と1との相違についてはよく分からない
タイラーコリア

44

酵素3、あなたが入力値を変更する必要がなく、解雇する必要がない場合はonChange(あなたはこの操作を行うことができます機能をnodeプロパティが削除されました):

wrapper.find('input').instance().value = "foo";

そのための小道具(つまり、制御されたコンポーネント)がある場合は、を使用wrapper.find('input').simulate("change", { target: { value: "foo" }})して呼び出すことができますonChange


7
NOTE: can only be called on a wrapper instance that is also the root instance.-airbnb.io/enzyme/docs/api/ShallowWrapper/instance.html
davidjb 2017

2
instance()を介してレンダリングされた場合は、任意の子ラッパーで呼び出すことができますmount
ウラジミールチェルバネフ2018

41

とった。(更新/改善されたバージョン)

  it('cancels changes when user presses esc', done => {
    const wrapper = mount(<EditableText defaultValue="Hello" />);
    const input = wrapper.find('input');

    input.simulate('focus');
    input.simulate('change', { target: { value: 'Changed' } });
    input.simulate('keyDown', {
      which: 27,
      target: {
        blur() {
          // Needed since <EditableText /> calls target.blur()
          input.simulate('blur');
        },
      },
    });
    expect(input.get(0).value).to.equal('Hello');

    done();
  });

これがどのように機能するのか興味があります。PhantomJSを使用しており、mount()コンポーネントをDOMに挿入しません。だから、彼らは焦点を合わせることができません。DOM要素を追加し、次のcontextオプションを使用する必要がありますmount()
Pre101 2016年

@ Pre101私は実際に酵素の代わりにJestを使い始めました。強くお勧めします!
ffxsam 2016年

1
@ffxsam:input.get(0).valueは常に「未定義」を表示します
Siddharth_Vyas

3
@Siddharth_Vyas tryinput.prop('value')
Ersel Aker

16

ここにはさまざまな意見があります。私のために働いた唯一のことは上記のどれでもなかった、それは使用していたinput.props().value。それがお役に立てば幸いです。


1
これは、入力の値を調べることができた唯一の答えです。
モハーベ

1
注目すべきinput.prop('value')は、プロップキーの名前がわかっている場合は、次を使用することもできます。
スターリングボーン

4

デフォルトでjestと酵素2.7.0が付属しているcreate-react-appを使用しています。

これは私のために働いた:

const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input')[index]; // where index is the position of the input field of interest
input.node.value = 'Change';
input.simulate('change', input);
done();

3

上記のどれも私のために働いていませんでした。これは、酵素^ 3.1.1で私のために働いたものです:

input.instance().props.onChange(({ target: { value: '19:00' } }));

コンテキストの残りのコードは次のとおりです。

const fakeHandleChangeValues = jest.fn();
  const fakeErrors = {
    errors: [{
      timePeriod: opHoursData[0].timePeriod,
      values: [{
        errorIndex: 2,
        errorTime: '19:00',
      }],
    }],
    state: true,
  };
const wrapper = mount(<AccessibleUI
    handleChangeValues={fakeHandleChangeValues}
    opHoursData={opHoursData}
    translations={translationsForRendering}
  />);
const input = wrapper.find('#input-2').at(0);
input.instance().props.onChange(({ target: { value: '19:00' } }));
expect(wrapper.state().error).toEqual(fakeErrors);

3

TypeScriptでreactを使用していますが、次のように機能しました

wrapper.find('input').getDOMNode<HTMLInputElement>().value = 'Hello';
wrapper.find('input').simulate('change');

値を直接設定する

wrapper.find('input').instance().value = 'Hello'` 

コンパイル警告が発生していました。


1

これは酵素2.4.1を使用して私のために働きます:

const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');

console.log(input.node.value);

4
Jest / enzymeを使い始めたときconsole.log、私はしばしばオブジェクトを作成し、(サブ)プロパティを調べて必要なものを取得していました。そうすることで、私は.nodeあなたが持っているように、しばしば何らかの形で使用することになりました。ただし、.node公式ドキュメントのいずれかで言及されているのを覚えていません。これは、公式に宣伝されているAPIの一部ではないため、リリース間で変更/破損する可能性があることを示唆しています。また、多くの場合、代替手段があるようです。例input.node.value=== input.get(0).value。だから、.nodeうまくいくかもしれません、そして私は時々それが良いハックを提供するだろうと思いますが、注意して使用してください。
Andrew Willems 2017年

これはもはやパブリックメソッドではありません。
faissaloo 2018

1

これが私のコードです。

const input = MobileNumberComponent.find('input')
// when
input.props().onChange({target: {
   id: 'mobile-no',
   value: '1234567900'
}});
MobileNumberComponent.update()
const Footer = (loginComponent.find('Footer'))
expect(Footer.find('Buttons').props().disabled).equals(false)

DOMを更新してからcomponentname.update() 、長さ10桁の送信ボタンの検証(無効化/有効化)を確認しています。


1

誰かが苦労している場合に備えて、私は次のことが私のために働いているのを見つけました

const wrapper = mount(<NewTask {...props} />); // component under test
const textField = wrapper.find(TextField);

textField.props().onChange({ target: { value: 'New Task 2' } })
textField.simulate('change');
// wrapper.update() didn't work for me, need to find element again

console.log(wrapper.find(TextField).props()); // New Task 2

(データを使用して変更イベントをシミュレートするのではなく)最初に変更イベントで何が発生するかを定義してから、それをシミュレートする必要があるようです。


これは私のために働いた。act()にonChangeイベントを配置する必要がありましたが。
パンカジ

0

私の場合、refコールバックを使用していました。

  <input id="usuario" className="form-control" placeholder="Usuario"
                                                       name="usuario" type="usuario"
                                                       onKeyUp={this._validateMail.bind(this)}
                                                       onChange={()=> this._validateMail()}
                                                       ref={(val) =>{ this._username = val}}
                                                    >

値を取得します。したがって、酵素はthis._usernameの値を変更しません。

だから私はしなければならなかった:

login.node._username.value = "mario@com.com";
    user.simulate('change');
    expect(login.state('mailValid')).toBe(true);

値を設定できるようにするには、changeを呼び出します。そして、主張します。


0

これは私のために働いた:

let wrapped = mount(<Component />);
expect(wrapped.find("input").get(0).props.value).toEqual("something");

0

私は非常に簡単な方法で解決しました:

  1. 小道具から値を設定します
  const wrapper: ShallowWrapper = shallow(<ProfileViewClass name: 'Sample Name' />);
  1. HTMLコード
  <input type='text' defaultValue={props.name} className='edituser-name' />
  1. から属性にアクセスしますwrapper.find(element).props().attribute-name
  it('should render user name', () => {
    expect(wrapper.find('.edituser-name').props().defaultValue).toContain(props.name);
  });

乾杯


0

Formikを使用していて、フィールド値を変更するとともにフィールドに「タッチ済み」のマークを付ける必要があったため、上記のソリューションはどれもうまくいきませんでした。次のコードは私のために働いた。

const emailField = orderPageWrapper.find('input[name="email"]')

emailField.simulate('focus')
emailField.simulate('change', { target: { value: 'test@example.com', name: 'email' } })
emailField.simulate('blur')


-1

.simulate()どういうわけか私には機能しません、私はそれnode.valueを呼び出す必要なしにアクセスするだけで機能しました.simulate(); あなたの場合:

const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input').at(0);

// Get the value
console.log(input.node.value); // Hello

// Set the value
input.node.value = 'new value';

// Get the value
console.log(input.node.value); // new value

これが他の人に役立つことを願っています!


以前はEnzymeReactWrapperインスタンスのプライベートプロパティであったReactWrapper :: nodeにアクセスしようとしましたが、現在は使用されていないため、依存しないでください。代わりにgetElement()メソッドの使用を検討してください。`` `
DaviLima19年

2
新しいバージョンのEnzymeの@DaviLimaは、または.nodeを使用する代わりに、結果をReactElementまたはDOMComponentのどちらとして使用したかによって異なります。.instance().getDOMNode()
JeeMok19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.