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
どんな助けでも大歓迎です
から 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')
上記の両方の答えを試しましたが、まだうまくいきません。
私にとって何がうまくいったか:
classNamePrefix
propを追加します-list
(他の回答で述べたように):
<Select
classNamePrefix='list'
options={[
{ label: 'one', value: 'one' },
{ label: 'two', value: 'two' }
]}/>
ドロップダウンインジケーターを選択し、mouseDown =>開かれたドロップダウンをシミュレートします。
wrapper
.find('.list__dropdown-indicator')
.simulate('mouseDown', {
button: 0
});
つまり、私の場合、ドロップダウンオプションの数を確認していました。
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');
キースの発言に加えて、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');
});
新しいバージョンの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: ... })
追加したいだけですが、実際にはhadを使用してclassNamePrefix
プロパティをSelect
コンポーネントに追加します。それ以外の場合は、*__control
ラッチするクラス。
誰かが酵素を使用している場合、これは私のために働きました:
wrapper.find('Select').simulate('change', {
target: { name: 'select', value: 1 },
});
ここで、「select」は、ここで定義されている属性の名前です。
<Select
name="select"
...
「値」は、希望するオプションの値です。
酵素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);
});
テストライブラリと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'});