onClick Jest / enzyme : วิธีการ “จำลอง” มีไว้เพื่อให้ทำงานบน 1 โหนด 0 พบแทน

ฉันไม่สามารถทดสอบ onClick สำหรับรหัสต่อไปนี้ด้านล่าง ฉันได้รับข้อผิดพลาดต่อไปนี้:

Method “simulate” is meant to be run on 1 node. 0 found instead.

รหัสส่วนประกอบของฉันมีลักษณะดังนี้:

constructor (props) {
  super(props)
  this.state = INITIAL_STATE;
}

handleQuickFilter = (type) => {
  this.setState({
    quickFilterObj: {...this.state.quickFilterObj, [type]: {...this.state.quickFilterObj[type], checked: !this.state.quickFilterObj[type].checked}}
    }, () => {
      let filter = this.buildFilter();
      filter ? 
        linker.UniversalGrid('Counterparty.Loa.Enrollment', '', `{form_filter}=$filter=(${filter}),{grid_selectable}=1,{can_add}=1`) 
      :
        linker.UniversalGrid('Counterparty.Loa.Enrollment', '', `{form_filter}='',{grid_selectable}=1,{can_add}=1`)
  })
}

render () {
  return(
    <div className='enrollment-grid-wrapper'>   
      <div className='quick-filter-div'>
        <button className={this.state.quickFilterObj['New'] && this.state.quickFilterObj['New'].checked ? 'checked quick-filter' : 'unchecked quick-filter'} 
                id = 'testnew'
                onClick={() => {this.handleQuickFilter('New')}}
                >
            New {this.state.quickFilterObj['New'] && this.state.quickFilterObj['New'].count !== undefined ? `(${this.state.quickFilterObj['New'].count})` : null}
        </button>
        <button className={this.state.quickFilterObj['Sent'] && this.state.quickFilterObj['Sent'].checked ? 'checked quick-filter' : 'unchecked quick-filter'} 
                onClick={()=>{this.handleQuickFilter('Sent')}}
                >
            Sent {this.state.quickFilterObj['Sent'] && this.state.quickFilterObj['Sent'].count !== undefined ? `(${this.state.quickFilterObj['Sent'].count})` : null}
        </button>
  )
}

ฉันได้ลองทำสิ่งต่อไปนี้โดยใช้ Jest / enzyme:

it("should HandlequickFilter with button click", () => { 
  wrapper.setProps({}); 
  wrapper.setState({quickFilterObj:"test"}); 
  wrapper.find('.quick-filter-div').at(0).simulate("click");
  expect(wrapper.state().quickFilterObj.New.checked).toEqual(true);
});

ฉันจะทำให้การทดสอบต่อไปนี้ผ่านได้อย่างไร


person user 9191    schedule 21.02.2019    source แหล่งที่มา
comment
คุณใช้โมดูล css หรือไม่? หากเป็นเช่นนั้น คุณจะไม่มี div ที่มีคลาส quick-filter-div แต่คลาสจะถูกเปลี่ยนชื่อเป็นคลาสที่มีสตริงเพิ่มเติมต่อท้าย   -  person Alvin S. Lee    schedule 21.02.2019
comment
ใช่. แล้วฉันจะทดสอบ onClick ได้อย่างไร   -  person user 9191    schedule 21.02.2019


คำตอบ (2)


เนื่องจากคุณใช้โมดูล css DOM ที่แสดงผลจริงของคุณจะไม่มี div ที่มีคลาส quick-filter-div ชั้นเรียนจะเป็นเช่น quick-filter-div__012xyz แทน ด้วยเหตุนี้ wrapper.find('.quick-filter-div') จึงส่งคืน 0 โหนด

คุณสามารถตรวจสอบได้โดยใส่บรรทัดต่อไปนี้ในการทดสอบหลังบรรทัด setState:

expect(wrapper.find('.quick-filter-div').exists()).toEqual(false)

แต่ดูเหมือนว่าสิ่งที่คุณต้องการทดสอบคือการคลิก button ภายใน div.quick-filter-div ของคุณ ไม่ถูกต้องเหรอ? ท้ายที่สุดแล้ว ตัวจัดการ onClick ก็เป็นอุปกรณ์ประกอบสำหรับ button ไม่ใช่ div

และเนื่องจาก button ของคุณได้รับรหัสแล้ว คุณสามารถดำเนินการดังนี้:

it("should HandlequickFilter with button click", () => { 
  wrapper.setProps({}); 
  wrapper.setState({quickFilterObj:"test"}); 
  const button = wrapper.find('button#testnew') // find button based on id selector
  expect(button.exists()).toEqual(true)         // make sure button is found
  button.simulate("click");                     // simulate click
  expect(wrapper.state().quickFilterObj.New.checked).toEqual(true);
});

หากคุณไม่ได้ระบุ ID ให้กับปุ่มของคุณ แต่คุณรู้ว่าการคลิกปุ่มที่คุณต้องการทดสอบนั้นเป็นปุ่มแรก (แทนที่จะเป็นปุ่มที่สอง) คุณสามารถลอง:

it("should HandlequickFilter with button click", () => { 
  wrapper.setProps({}); 
  wrapper.setState({quickFilterObj:"test"}); 
  const buttons = wrapper.find('button')        // find all buttons
  expect(buttons).toHaveLength(2)               // make sure you found 2 buttons
  const button = buttons.at(0)                  // get the first button
  button.simulate("click");                     // simulate click
  expect(wrapper.state().quickFilterObj.New.checked).toEqual(true);
});
person Alvin S. Lee    schedule 21.02.2019
comment
ทั้งสองคนไม่ทำงาน สำหรับคำตอบแรกฉันได้รับเท็จแทนที่จะเป็นจริง อันที่สองนั้นซับซ้อนกว่ามาก - ฉันก็ผิดเช่นกันและคาดหวัง: แสดงทุกสิ่งภายใต้การเรนเดอร์ - person user 9191; 21.02.2019
comment
@ user9191 คุณใช้ render หรือ shallow ของ Enzyme หรือไม่? วิธีนี้ใช้ได้ผลหากคุณใช้ shallow ลองตั้งค่า wrapper = shallow(<YourComponent />) แทน render - person Alvin S. Lee; 21.02.2019
comment
ใช้ตื้น - วิธีที่คุณอธิบายไว้ข้างต้น - person user 9191; 21.02.2019
comment
ฉันเพิ่มข้อมูลเพิ่มเติมเกี่ยวกับคำถามของฉันซึ่งอาจช่วยค้นหาปัญหาได้ โปรดดู - person user 9191; 21.02.2019
comment
@ user9191 คุณสามารถโพสต์รหัส jest/enzyme ของคุณได้ไหม? สิ่งสำคัญที่สุดคือ คุณจะประกาศและกำหนด wrapper ได้อย่างไร? - person Alvin S. Lee; 21.02.2019
comment
@ user9191 อย่างไรก็ตาม ในบรรทัด setState ของโค้ดส่วนประกอบของคุณ คุณมี quickFilterObj: {...this.state.quickFilterObj, [type] - นั่นเป็นการพิมพ์ผิดหรือเปล่า? คุณหมายถึงให้มีลูกน้ำตรงนั้นหรือควรจะเป็น quickFilterObj: {...this.state.quickFilterObj[type]: ? - person Alvin S. Lee; 21.02.2019
comment
มันควรจะมีลูกน้ำตรงนั้น - - person user 9191; 21.02.2019
comment
อะไรทำให้เกิดปัญหา? - person user 9191; 21.02.2019
comment
คุณได้ลองใช้ shallow แทน render แล้วหรือยัง? คุณสามารถโพสต์รหัส jest/enzyme ของคุณได้ไหม? - person Alvin S. Lee; 21.02.2019
comment
ฉันใช้ตื้นแทนการเรนเดอร์ - person user 9191; 21.02.2019
comment
@ user9191 ผลลัพธ์คืออะไร? - person Alvin S. Lee; 21.02.2019
comment
ผลลัพธ์เหมือนเดิมไม่ผ่าน - person user 9191; 21.02.2019
comment
เมื่อดูโค้ด LOA ของคุณ ฉันพบว่ามีปุ่มในส่วนประกอบของคุณมากกว่า 2 ปุ่ม ดังนั้นในตัวอย่างการทดสอบที่สองของฉันด้านบน คุณควรลอง expect(buttons).toHaveLength(9) ตามด้วย const button = buttons.at(2) นอกจากนี้ ฉันไม่สามารถรันการทดสอบ LOA ของคุณในแซนด์บ็อกซ์โค้ดได้ เพราะว่า Could not find module in path: '../../Utils/UniversalLinker' relative to '/src/components/LOA/LOA.js' - person Alvin S. Lee; 21.02.2019
comment
นำเข้า * เป็นตัวเชื่อมโยงจาก '../../Utils/UniversalLinker'; ?? - person user 9191; 21.02.2019
comment
นอกจากนี้ ฉันได้ปรับเป็น 9 และ 2 แล้ว - ยังล้มเหลวอยู่ - person user 9191; 21.02.2019
comment
ใช่ ฉันต้องแก้ไข setState ของฉันเพื่อที่จะผ่าน ฉันจะดูมันในภายหลัง คุณช่วยกรุณาแก้ไขความคิดเห็นก่อนหน้า - ไม่ต้องการลิงก์แซนด์บ็อกซ์ที่นี่ .. ขอบคุณสำหรับความช่วยเหลือ - person user 9191; 21.02.2019
comment
ด้วยความยินดี. ฉันจะลบแซนด์บ็อกซ์แบบแยกและลบความคิดเห็น ฉันหวังว่าคำตอบนั้นจะช่วยคุณได้ หากเป็นเช่นนั้น โปรดพิจารณายอมรับคำตอบของฉัน ขอให้มีความสุขในการเขียนโค้ด! - person Alvin S. Lee; 21.02.2019
comment
แก้ไขคำตอบแล้ว - ลองดู - person user 9191; 28.02.2019

ต้องเพิ่ม return new Promise ในฟังก์ชัน jest.fn ของคุณ

//mocking functions
getSelectedLOAs  = jest.fn( () => {
return new Promise((resolve, reject) => {
resolve()
})
});


it("should test click event NEW  method", () => {
wrapper.setProps({
});
wrapper.find('COMPONENT').setState({ 
  quickFilterObj:{
    New: {
      checked: true
    },
    Sent: {
      checked: true
    },

   }, } );
wrapper.update();
wrapper.find('#New-testclick').simulate("click");
wrapper.find('#Sent-testclick').simulate("click");
person user 9191    schedule 28.02.2019