私はreactjsと酵素ツールを初めて使用し、reactjsアプリケーションの単体テストを実装しています。親にある子コンポーネントの props 値を渡すたびに、それらの値は子の必須フィールドに割り当てられているようには見えません。しかし、私が子供に直接同じことをすると、うまくいきます。以下は、子コンポーネントのレンダリング部分です
render: function() {
var phoneInputClassnames = Classnames('phoneInput', {'focused':this.state.focused}, this.props.className);
var countryList = (
<div style={styles.listConainer} className="card">
<ul style={styles.countryList}>
{
this.props.suggestions.map(function(country, i){
var handleClick = this.handleClickCountry.bind(this, country);
return <CountryItem key={i} country={country} onMouseDown={handleClick}/>
}, this)
}
</ul>
<span style={styles.separator}></span>
<ul style={styles.countryList}>
{
this.props.countryData.map(function(country, i){
var handleClick = this.handleClickCountry.bind(this, country);
return <CountryItem key={i} country={country} onMouseDown={handleClick}/>
},this)
}
</ul>
</div>
);
return (
<div className={phoneInputClassnames} onFocus={this.parentOnFocus}>
<div>
<span>
<Dropdown
ref = "dropdown"
label = {<button>{this.state.selectedCountry.dial_code} <i className="fa fa-caret-down" aria-hidden="true"></i></button>}
content = {countryList}
offsetX = {this.props.dropdownOffset || -6}
offsetY = {44}
onClose = {this.focusInput}
/>
</span>
<span>
<input
type = "text"
ref = "phoneInput"
placeholder = "Phone"
value = {this.props.value || ''}
onKeyDown = {this.inputKeyDown}
onChange = {this.numberOnChange}
onFocus={this.inputOnFocus}
onBlur={this.inputOnBlur}/>
</span>
</div>
</div>
)
}
そして、以下に示す親コンポーネントのレンダリング関数
render: function() {
var input;
if (this.state.loginState === SessionStore.STATES.LOGIN) {
input = (
<div>
<h1>Welcome</h1>
<p>Login to manage your business.</p>
<div className="tabs">
<i onClick={this.tabSelect} data-tab="0" className={"fa fa-phone" + (this.state.tab == 0? " active": "")} aria-hidden="true"></i>
<i onClick={this.tabSelect} data-tab="1" className={"fa fa-at" + (this.state.tab == 1? " active": "")} aria-hidden="true"></i>
</div>
<div className="inputs">
{(function() {
if (this.state.tab == 0) {
return <PhoneNumber
countryData = {Countries.countryData}
suggestions = {Countries.popularCountryData}
onChange = {this.phoneInputListener}
onSubmit = {this.login}
autofocus = {true}
value = {this.state.clientNumber}
selectedCountry = {this.state.clientCountry}
validationHandler = {Countries.validatePhoneNumber}/>;
} else {
return <SmartInput
className = "email"
placeholder = "Email"
value = {this.state.clientEmail}
onChange = {this.emailInputOnChange}
onSubmit = {this.emailInputListener}/>;
}
}.bind(this))()}
</div>
{(function() {
if (this.state.error) {
return <p className="errorText">{this.textError()}</p>
}
}.bind(this))()}
{(function() {
if (this.state.loading) {
return <button className="button disabled" type="button"><i className="fa fa-spinner fa-pulse fa-fw margin-bottom"></i></button>;
} else {
return <button className="button" type="button" onClick={this.login}>Continue</button>;
}
}.bind(this))()}
</div>
);
} else if (this.state.loginState === SessionStore.STATES.OTP) {
input = (
<div className="otp">
{(function() {
if (this.state.tab == 0) {
return (
<div>
<h2>Check your Twnel!</h2>
<p>
You will shortly receive a login code sent to {util.formatPhoneNumber(this.state.clientCountry.dial_code + this.state.clientNumber)}.
<span onClick={this.goBack}> (Not me)</span>
</p>
</div>
);
} else {
return (
<div>
<h2>Check your Email!</h2>
<p>
You will shortly receive a login code sent to {this.state.clientEmail}.
<span onClick={this.goBack}> (Not me)</span>
</p>
</div>
);
}
}.bind(this))()}
<SmartInput
placeholder = "Code"
onChange = {this.otpInputOnChange}
onSubmit = {this.otpInputListener} />
{(function() {
if (this.state.error) {
return <p className="errorText">{this.textError()}</p>
}
}.bind(this))()}
{(function() {
if (this.state.loading) {
return <button className="button disabled" type="button"><i className="fa fa-spinner fa-pulse fa-fw margin-bottom"></i></button>;
} else {
return <button className="button" type="button" onClick={this.validate}>Continue</button>;
}
}.bind(this))()}
</div>
);
}
return (
<div id="login" className="card">
{input}
</div>
);
},
実際に、ここでログイン操作をテストしています。私はreactjsとenzymeの両方に慣れていないので、正しい方法で行っているかどうかわかりません。以下は私のサンプルテストスニペットです
it('find the tab state', () => {
// console.log(wrapper.find('button').last().simulate('click'));
const wrapper2 = mount(<PhoneNumber value="1234567890" countryData= {Countries} suggestions={item}/>);
const wrapper = mount(<Login className="sample2" placeholder="enter something" value="1234567890" countryData={Countries} />);
console.log(wrapper2.debug());
expect(wrapper.find('.phoneInput')).to.have.length(1);
});
ここで問題を解決するために誰かが手を差し伸べてくれれば幸いです。