web-dev-qa-db-ja.com

テストReactコンポーネントを選択

https://github.com/JedWatson/react-select

React-Select反応コンポーネントを使用したいのですが、テストを追加する必要があります。

私はグーグルで見つけたいくつかのオプションを試しましたが、何もうまくいかないようです。以下のコードがありますが、変更イベントは発生していません。 「is-focussed」クラスを追加するフォーカスイベントを追加できましたが、「is-open」クラスがまだありません。

私は使用しました: https://github.com/JedWatson/react-select/blob/master/test/Select-test.js 参照として

入力フィールドでのみ変更イベントを使用しようとしましたが、これも役に立ちませんでした。 onInputChange={this.change}は選択用です。

テスト

import Home from '../../src/components/home';
import { mount } from 'enzyme'

describe('Home', () => {

it("renders home", () => {

    const component = mount(<Home/>);

    // default class on .Select div
    // "Select foobar Select--single is-searchable"

    const select = component.find('.Select');

    // After focus event
    // "Select foobar Select--single is-searchable is-focussed"
    // missing is-open
    TestUtils.Simulate.focus(select.find('input'));

    //this is not working
    TestUtils.Simulate.keyDown(select.find('.Select-control'), { keyCode: 40, key: 'ArrowDown' });
    TestUtils.Simulate.keyDown(select.find('.Select-control'), { keyCode: 13, key: 'Enter' });

    // as per code below I expect the h2 to have the select value in it eg 'feaure'

});
});

テスト対象のコンポーネント

import React, { Component } from 'react';
import Select from 'react-select';

class Home extends Component {
constructor(props) {
    super(props);

    this.state = {
        message: "Please select option"};
    this.change = this.change.bind(this);
}

change(event) {

    if(event.value) {
        this.setState({message: event.label});
    }
}

render () {

    const options = [ {label: 'bug', value: 1} , {label: 'feature', value: 2 }, {label: 'documents', value: 3}, {label: 'discussion', value: 4}];

    return (
      <div className='content xs-full-height'>
          <div>
              <h2>{this.state.message}</h2>

              <Select
                  name="select"
                  value={this.state.message}
                  options={options}
                  onInputChange={this.change}
                  onChange={this.change}
              />

          </div>
        </div>
    );
}
}

export default Home;

コマンドラインテストを実行するには、次のようにします。

>> npm run test

そしてpackage.jsに私はこのスクリプトを持っています:

"test": "mocha --compilers js:babel-core/register -w test/browser.js ./new",

テスト設定

そしてbrowser.jsは:

import 'babel-register';
import jsdom from 'jsdom';

const exposedProperties = ['window', 'navigator', 'document'];

global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.defaultView;
Object.keys(document.defaultView).forEach((property) => {
   if (typeof global[property] === 'undefined') {
       exposedProperties.Push(property);
       global[property] = document.defaultView[property];
   }
});

global.navigator = {
    userAgent: 'node.js'
};

ここで概説されているテスト用のメソッドを使用してみました: https://github.com/StephenGrider/ReduxSimpleStarter

どんな助けでも大歓迎です

16
Llewellyn

から https://github.com/JedWatson/react-select/issues/1357

私が見つけた唯一の解決策は、キーダウンイベントを通じて選択をシミュレートすることでした:

wrapper.find('.Select-control').simulate('keyDown', { keyCode: 40 });
// you can use 'input' instead of '.Select-control'
wrapper.find('.Select-control').simulate('keyDown', { keyCode: 13 });
expect(size).to.eql('your first value in the list')
16
Keith

上記の両方の答えを試しましたが、まだうまくいきません。

私にとって何がうまくいったか:

  1. classNamePrefix propを追加します-list(他の回答で述べたように):

    <Select
       classNamePrefix='list'
       options={[
         { label: 'one', value: 'one' },
         { label: 'two', value: 'two' }
    ]}/>
    
  2. ドロップダウンインジケーターを選択し、mouseDown =>開かれたドロップダウンをシミュレートします。

    wrapper
      .find('.list__dropdown-indicator')
      .simulate('mouseDown', {
        button: 0 
      });
    
  3. つまり、私の場合、ドロップダウンオプションの数を確認していました。

    expect(wrapper.find('.list__option').length).toEqual(2);
    

    送信される小道具を制御できる場合は、menuIsOpen小道具を追加して、常にメニューを開いたままにすることができます(リストのステップ2とも呼ばれます)。

ドロップダウンを開いた後、ドロップダウンから値を選択するには:

wrapper.find('.list__option').last().simulate('click', null);

次に、次のいずれかをテストできます。

expect(wrapper.find('.list__value-container').text()).toEqual('two');

または

expect(wrapper.find('.list__single-value').text()).toEqual('two');
14
Sanda

キースの発言に加えて、simulateメソッドを使用することが機能を実行する唯一の方法のようです。しかし、私の解決策でこれを試したところ、うまくいきませんでした-TypeScriptを使用していますが、これにベアリングがあるかどうかはわかりませんが、シミュレーション時にkeyプロパティも渡す必要があることがわかりましたイベント:

wrapper.find('.Select-control').simulate('keyDown', { key: 'ArrowDown', keyCode: 40 });
wrapper.find('.Select-control').simulate('keyDown', { key: 'Enter', keyCode: 13 });

classNamePrefixプロパティを設定すると、コンポーネントがシミュレートされたイベントに正しく応答していることを確認するための簡単なテストがはるかに簡単になることもわかりました。このプレフィックスを設定すると、コンポーネントの便利な部分がクラス名で装飾され、簡単にアクセスできるようになります(これらの便利なクラス名は、Google開発ツールの要素を調べることで識別できます)。簡単なJestテスト:

it('react-select will respond to events correctly', () => {
    const sut = Enzyme.mount(
    <Select 
        classNamePrefix="list" 
        options={[{ label: 'item 1', value: 1 }]}
    />);

    // The intereactive element uses the suffix __control **note there are two underscores** 
    sut.find('.list__control').first().simulate('keyDown', { key: 'ArrowDown', keyCode: 40 });
    sut.find('.list__control').first().simulate('keyDown', { key: 'Enter', keyCode: 13 });

    // the selected value uses the suffix __single-value **note there are two underscores** 
    expect(sut.find('.list__single-value').first().text()).toEqual('item 1');
});
3
Code Ranger

新しいバージョンのreact-select(2.x +)では、react-selectが感情を使用するため、上記の方法は機能しません。したがって、wrapper.find('.Select-control')またはwrapper.find('.list__option')は機能しなくなります。 react-select 2.x +は、Selectコンポーネントを状態マネージャー内にラップしますが、onChangeコンポーネントのSelectメソッドにアクセスできます。次のコードを使用して選択をトリガーします。

wrapper.find(Select).props().onChange({ value: ... })
2
Armin Primadi

追加したいだけですが、実際にはhadを使用してclassNamePrefixプロパティをSelectコンポーネントに追加します。それ以外の場合は、*__controlラッチするクラス。

1
Quinton Aiken

誰かが酵素を使用している場合、これは私のために働きました:

  wrapper.find('Select').simulate('change', {
    target: { name: 'select', value: 1 },
  });

ここで、「select」は、ここで定義されている属性の名前です。

  <Select
      name="select"
      ...

「値」は、希望するオプションの値です。

0
AnaPana

酵素v3.11.0とreact-select v3.0.8を使用している人にとって、これは私にとってうまくいきました

component.find('Select').simulate('keyDown', { key: 'ArrowDown', keyCode: 40 });

これが私のSelectです。 redux-formと一緒に使用しています

<Select
    {...input}
    styles={customStyles}
    options={props.options}
    formatGroupLabel={formatGroupLabel}
    placeholder="Custom Search..."
    isSearchable={true}
    onBlur={handleBlur}
/>

テストのサンプル

it('should render dropdown on keyDown', () => {
    expect(component.find('MenuList').length).toEqual(1);
});

it('should render the correct amount of options', () => {
    expect(component.find('Option').length).toEqual(optionsLength);
});
0
Sasha

テストライブラリとv2.0の使用

classNamePrefixのような非常に具体的なものを使用したり、onChangeプロップなどを探してコンポーネントの動作をハッキングしたりしないようにします。

const callback = jest.fn();
const { container, getByText} = render(<Select ... onChange={callback} />);

今は基本的にスクリーンリーダーのふりをしてフォーカスし、下矢印キーを押します。

fireEvent.focus(container.querySelector('input'));
fireEvent.keyDown(container.querySelector('input'), { key: 'ArrowDown', code: 40 });

そして今あなたが望む値をクリックしてください

fireEvent.click(getByText('Option Two'));

そして断言する。

expect(callback).toHaveBeenCalledWith({ value: 'two', label: 'Option Two'});
0
Dmitriy Likhten