คุณควรใช้การเรนเดอร์และตื้นในการทดสอบเอนไซม์ / ปฏิกิริยาเมื่อใด


100

ก่อนที่จะโพสต์คำถามนี้ฉันพยายามค้นหาใน sqa stackexchange แต่ฉันไม่พบโพสต์เกี่ยวกับตื้นและแสดงผลที่นั่นดังนั้นฉันหวังว่าจะมีคนช่วยฉันได้ที่นี่

ฉันควรใช้ตื้นและเรนเดอร์ในการทดสอบส่วนประกอบปฏิกิริยาเมื่อใด จากเอกสารของ airbnb ฉันได้แสดงความคิดเห็นเกี่ยวกับความแตกต่างของทั้งสอง:

  1. เนื่องจากตื้นเป็นการทดสอบส่วนประกอบเป็นหน่วยดังนั้นจึงควรใช้สำหรับส่วนประกอบ "หลัก" (เช่นตารางกระดาษห่อ ฯลฯ )

  2. Render มีไว้สำหรับส่วนประกอบย่อย

เหตุผลที่ฉันถามคำถามนี้คือฉันมีเวลายากที่จะคิดว่าฉันควรใช้อันไหน (แม้ว่าเอกสารจะบอกว่าคล้ายกันมากก็ตาม)

ดังนั้นฉันจะรู้ได้อย่างไรว่าควรใช้อันไหนในสถานการณ์เฉพาะ


2
ความแตกต่างระหว่างตื้น () และเมาท์ () คือส่วนตื้น () ทดสอบส่วนประกอบแยกจากส่วนประกอบลูกที่แสดงผลในขณะที่เมาท์ () ลึกลงไปและทดสอบลูกของส่วนประกอบ สำหรับตื้น () หมายความว่าหากองค์ประกอบหลักแสดงผลองค์ประกอบอื่นที่ไม่สามารถแสดงผลได้การแสดงผลตื้น () บนพาเรนต์จะยังคงผ่านไป
Shyam Kumar

คำตอบ:


169

ตามเอกสารของเอนไซม์:

mount(<Component />) สำหรับการแสดงผล DOM เต็มรูปแบบเหมาะอย่างยิ่งสำหรับกรณีการใช้งานที่คุณมีส่วนประกอบที่อาจโต้ตอบกับ DOM apis หรืออาจต้องใช้อายุการใช้งานเต็มรูปแบบเพื่อทดสอบส่วนประกอบอย่างสมบูรณ์ (เช่น componentDidMount เป็นต้น)

เทียบกับ

shallow(<Component />) สำหรับการเรนเดอร์แบบตื้นมีประโยชน์ในการ จำกัด ตัวคุณเองในการทดสอบส่วนประกอบเป็นหน่วยและเพื่อให้แน่ใจว่าการทดสอบของคุณไม่ได้เป็นการยืนยันพฤติกรรมของส่วนประกอบย่อยโดยอ้อม

เทียบกับ

renderซึ่งใช้ในการแสดงผลคอมโพเนนต์ปฏิกิริยาเป็นHTML แบบคงที่และวิเคราะห์โครงสร้าง HTML ที่เป็นผลลัพธ์

คุณยังสามารถเห็น "โหนด" ที่อยู่ภายใต้การเรนเดอร์แบบตื้นได้ตัวอย่างเช่นคุณสามารถทำบางสิ่งเช่นนี้ (สร้างขึ้นเล็กน้อย) ตัวอย่างโดยใช้AVAเป็นตัวเรียกข้อมูลจำเพาะ:

let wrapper = shallow(<TagBox />);

const props = {
    toggleValue: sinon.spy()
};

test('it should render two top level nodes', t => {
    t.is(wrapper.children().length, 2);
});

test('it should safely set all props and still render two nodes', t => {
    wrapper.setProps({...props});
    t.is(wrapper.children().length, 2);
});

test('it should call toggleValue when an x class is clicked', t => {
    wrapper.setProps({...props});
    wrapper.find('.x').last().simulate('click');
    t.true(props.toggleValue.calledWith(3));
});

ขอให้สังเกตว่าการแสดงผล , การตั้งค่าอุปกรณ์ประกอบฉากและการหาตัวเลือกและแม้กระทั่งเหตุการณ์ที่สังเคราะห์ได้รับการสนับสนุนโดยการแสดงผลตื้นเพื่อให้มากที่สุดเท่าที่คุณสามารถใช้เพียงว่า

แต่คุณจะไม่สามารถรับวงจรการใช้งานเต็มรูปแบบของส่วนประกอบได้ดังนั้นหากคุณคาดว่าสิ่งต่างๆจะเกิดขึ้นใน componentDidMount คุณควรใช้mount(<Component />);

การทดสอบนี้ใช้Sinonเพื่อสอดแนมส่วนประกอบcomponentDidMount

test.only('mount calls componentDidMount', t => {

    class Test extends Component {
        constructor (props) {
            super(props);
        }
        componentDidMount() {
            console.log('componentDidMount!');
        }
        render () {
            return (
                <div />
            );
        }
    };

    const componentDidMount = sinon.spy(Test.prototype, 'componentDidMount');
    const wrapper = mount(<Test />);

    t.true(componentDidMount.calledOnce);

    componentDidMount.restore();
});

ข้างต้นจะไม่ผ่านการแสดงผลแบบตื้นหรือการแสดงผล

render จะให้ html แก่คุณเท่านั้นดังนั้นคุณยังสามารถทำสิ่งต่างๆเช่นนี้ได้:

test.only('render works', t => {

    // insert Test component here...

    const rendered = render(<Test />);
    const len = rendered.find('div').length;
    t.is(len, 1);
});

หวังว่านี่จะช่วยได้!


1
ฉันยังไม่ได้ 100% ทำไมคำกริยาทั้งสามจึงใช้วิธีการที่แตกต่างกัน ตัวอย่างเช่นเราสามารถใช้ wrapper.getNode () แบบตื้น แต่ไม่สามารถใช้ในการแสดงผล คำอธิบาย / ลิงค์ / เอกสาร / บล็อกใด ๆ ที่ช่วยให้ฉันได้รับ togehter นี้
Paulquappe

@HenryZhu ควรมีความชัดเจนจากเอกสารที่การเรนเดอร์มีส่วนเกี่ยวข้องมากกว่าตื้นเนื่องจากพยายามเลียนแบบทรี DOM สำหรับโหนดส่วนประกอบเฉพาะนั้น
อายุ

13
การย้ายเอนไซม์จาก v2 เป็น v3 ทำให้วิธีวงจรชีวิตถูกเปิดใช้โดยค่าเริ่มต้นในระดับตื้นเช่นกันgithub.com/airbnb/enzyme/blob/master/docs/guides/…
Abhinav Singi

2
คำอธิบายเพิ่มเติมที่ดีเกี่ยวกับความแตกต่างอยู่ที่นี่github.com/airbnb/enzyme/issues/465#issuecomment-227697726และที่นี่github.com/airbnb/enzyme/issues/465#issuecomment-229116418
Dmitry Gonchar

10

ความแตกต่างระหว่างตื้น () และเมาท์ () คือส่วนตื้น () ทดสอบส่วนประกอบแยกจากส่วนประกอบลูกที่แสดงผลในขณะที่เมาท์ () ลึกลงไปและทดสอบลูกของส่วนประกอบ

สำหรับตื้น () หมายความว่าหากองค์ประกอบหลักแสดงผลองค์ประกอบอื่นที่ไม่สามารถแสดงผลได้การแสดงผลตื้น () บนพาเรนต์จะยังคงผ่านไป


เมื่อฉันจะทดสอบpropsส่วนประกอบฉันควรใช้shallowและmount?
Menai Ala Eddine - Aladdin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.