एंजाइम - <इनपुट> मान कैसे एक्सेस और सेट करें?


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 />, यह मान सेट करने लगता है। ऊपर दूसरा कोड ब्लॉक मान प्रिंट करता है, और इसी तरह अगर मैं क्रोम में इनपुट तत्व का निरीक्षण करता हूं और $0.valueकंसोल में टाइप करता हूं , तो यह अपेक्षित मान दिखाता है।

जवाबों:


100

मुझे लगता है कि तुम क्या चाहते हो:

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

यहाँ मेरा स्रोत है

render()मूल्य निर्धारित करने के लिए आपको कहीं भी उपयोग करने की आवश्यकता नहीं है । और सिर्फ FYI करें, आप दो अलग-अलग उपयोग कर रहे हैं render()। आपके पहले कोड ब्लॉक में से एक एंजाइम से है, और आवरण ऑब्जेक्ट पर एक विधि है mountऔर findआपको देता है। दूसरा एक, हालांकि यह 100% स्पष्ट नहीं है, शायद इससे एक है react-dom। यदि आप एंजाइम का उपयोग कर रहे हैं, तो उचित रूप में उपयोग करें shallowया इसकी mountकोई आवश्यकता नहीं renderहै react-dom


input.render()नहीं है react-domप्रस्तुत करना। यह यह है: airbnb.io/enzyme/docs/api/ShallowWrapper/render.html
ffxsam

3
इसके अलावा, shallow()किसी कारण से काम नहीं करता है .. focusघटना एक ऐसी विधि को ट्रिगर करती है जो संदर्भ की कोशिश करती है this.refs.input, जो विफल हो जाती है। लेकिन जब मैं इसके shallowलिए स्वैप mountकरता हूं , तो यह उम्मीद के मुताबिक काम करता है। ज्यादातर .. (ESC कुंजी के अनुकरण के साथ एक और मुद्दा)
ffxsam

मुझे और अधिक स्पष्ट होना चाहिए था। मेरा मतलब था कि जैसा दिखता है रेंडर render(<EditableText defaultValue="Hello" />)। मुझे लगता है कि आपके उपयोग का मामला मेरे विचार से अधिक विशिष्ट है; मैं इसे केवल इनपुट मूल्य सेट करने पर ध्यान देने और "परिवर्तनों को रद्द करने" के साथ नोट करता हूं। यह बहुत अच्छा होगा यदि आप एक प्लंकर बना सकते हैं ।
टायलर कोलियर

नमस्ते, मुझे इस तरह के डिफ़ॉल्ट मानों के साथ मुद्दा मिला this.state = {inputNum: 10};, और प्राप्त हमेशा 1 रहेगा हालांकि अपेक्षित 100 के रूप में सेट है input.simulate('change', { target: { value: '100' } })। किसी को भी मदद कर सकता है?
नंबक

@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

2
instance()किसी भी बच्चे को रैपर पर बुलाया जा सकता है अगर वह इसके माध्यम से प्रदान किया गया हो mount
व्लादिमीर चेरनेव

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 में घटक सम्मिलित नहीं करते हैं। इसलिए, वे फोकस प्राप्त नहीं कर सकते हैं। हम एक डोम तत्व जोड़ सकते हैं और उपयोग करने के लिए contextके लिए विकल्पmount()
Pre101

@ Pre101 मैं वास्तव में एंजाइम के बजाय जेस्ट का उपयोग करना शुरू कर दिया। अत्यधिक सिफारिशित!
ffxsam

1
@ffxsam: input.get (0) .value हमेशा "अपरिभाषित" प्रदर्शित करता है
सिद्धार्थ_वाईस

3
@ सिद्धार्थ_व्यास कोशिश करते हैंinput.prop('value')
एरसेल

16

यहाँ बहुत सारे विभिन्न मत हैं। केवल एक चीज जो मेरे लिए काम करती थी, उपरोक्त में से कोई भी नहीं थी, वह उपयोग कर रही थी input.props().value। मुझे आशा है कि वह मदद करेंगे।


1
यह एकमात्र उत्तर है जिसने मुझे इनपुट के मूल्य पर पूछताछ करने की अनुमति दी।
मोजावे

1
ध्यान दें, आप यह भी उपयोग कर सकते हैं: input.prop('value')यदि आप अपनी प्रोप कुंजी का नाम जानते हैं।
स्टर्लिंग बॉर्न

4

मैं क्रिएट-रिएक्शन-ऐप का उपयोग कर रहा हूं जो डिफ़ॉल्ट रूप से कीट और 2.7.0 एंजाइम के साथ आता है।

यह मेरे लिए काम किया:

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

मैं टाइपस्क्रिप्ट के साथ प्रतिक्रिया का उपयोग कर रहा हूं और निम्नलिखित मेरे लिए काम करता है

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
जब मैंने जेस्ट / एंजाइम का उपयोग करना शुरू किया तो मैं अक्सर console.logएक वस्तु (खुदाई) गुणों के माध्यम से खोदता हूं जो मुझे चाहिए। ऐसा करते हुए, मैं अक्सर .nodeकिसी न किसी रूप में उपयोग करना समाप्त कर देता हूं , जैसे आपके पास है। हालाँकि, मुझे याद नहीं है .nodeकि किसी भी आधिकारिक दस्तावेज में इसका उल्लेख किया गया है, यह सुझाव देता है कि यह रिलीज के बीच बदल सकता है / टूट सकता है क्योंकि यह आधिकारिक तौर पर विज्ञापित एपीआई का हिस्सा नहीं है। इसके अलावा, अक्सर विकल्प प्रतीत होते हैं। जैसे input.node.value=== input.get(0).value। तो, .nodeकाम कर सकता है, और मुझे संदेह है कि कभी-कभी यह एक अच्छा हैक प्रदान करेगा, लेकिन सावधानी के साथ उपयोग करें।
एंड्रयू विल्म्स

यह अब एक सार्वजनिक तरीका नहीं है।
Faissaloo

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

ऐसा लगता है कि आपको यह परिभाषित करने की आवश्यकता है कि पहले परिवर्तन घटना में क्या होता है और फिर इसे अनुकरण करें (डेटा के साथ परिवर्तन घटना का अनुकरण करने के बजाय)


इसने मेरे लिए काम किया। हालांकि मुझे onChange घटना को अधिनियम () में रखना था।
पंकज 5

0

मेरे मामले में मैं रेफरी कॉलबैक का उपयोग कर रहा था,

  <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}}
                                                    >

मान प्राप्त करना। तो एंजाइम इस का मान नहीं बदलेगा।

इसलिए मुझे यह करना पड़ा:

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

मान सेट करने में सक्षम होने के लिए तब परिवर्तन कॉल करें। और फिर मुखर।



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

ऊपर दिए गए किसी भी समाधान ने मेरे लिए काम नहीं किया क्योंकि मैं फॉर्मिक का उपयोग कर रहा था और मुझे फ़ील्ड मान को बदलने के साथ-साथ "छुआ हुआ" क्षेत्र को चिह्नित करने की आवश्यकता थी। निम्नलिखित कोड ने मेरे लिए काम किया।

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

आशा है कि यह दूसरों के लिए मदद करता है!


फेंकता है `` ReactWrapper का उपयोग करने का प्रयास किया :: नोड, जो पहले Enzyme ReactWrapper उदाहरणों पर एक निजी संपत्ति थी, लेकिन अब नहीं है और उस पर भरोसा नहीं किया जाना चाहिए। इसके बजाय getElement () विधि का उपयोग करने पर विचार करें। `` `
डेवी लीमा

2
@DaviLima एंजाइम के नए संस्करण के लिए, इसके बजाय .nodeआपको उपयोग करना चाहिए.instance() या .getDOMNode(), निर्भर करता है कि क्या आपने परिणाम का उपयोग एक ReactElement या DOMComponent के रूप में किया है।
जी मोक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.