ค้นหาเว็บไซต์

typescript - การทดสอบเมธอดส่วนตัวใน JestJS


ฉันกำลังสร้าง API ด้วย NestJS (โดยใช้ TypeScript) และมันใช้ JestJS เป็นเฟรมเวิร์กการทดสอบเริ่มต้น ฉันกำลังเขียนการทดสอบสำหรับคลาสเซอร์วิสและพยายามเข้าถึงฟังก์ชันส่วนตัวของมัน (ถูกบังคับด้วย TypeScript) แต่ฉันไม่สามารถทำได้ด้วยเหตุผลที่ชัดเจน

วิธีแก้ปัญหาแบบดั้งเดิมในภาษาอื่น (เช่น Java) คือการเปลี่ยนฟังก์ชันให้อยู่ในขอบเขต package หรือ internal แต่สิ่งนี้ไม่มีใน TypeScript

ฉันจะเข้าถึงฟังก์ชันเหล่านั้นเพื่อการทดสอบได้อย่างไร แต่ยังคงบังคับการเข้าถึงแบบส่วนตัว (ตามหลักปฏิบัติที่ดี)?

คำตอบ #1

เป็นแนวทาง คุณควรจะสามารถทดสอบคลาสโดยใช้เมธอดสาธารณะของมันได้ หากมีฟังก์ชันสำคัญซ่อนอยู่ภายในการเข้าถึงแบบส่วนตัว/ป้องกัน มันอาจเป็นสัญญาณว่าควรสามารถแยกออกไปยังคลาสอื่นได้

เป็นไปได้ไหมที่คุณจะแยกวิธีส่วนตัวที่ซับซ้อนออกไปอยู่ในคลาสอื่น ๆ ที่คุณสามารถทดสอบแยกต่างหากได้?

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

แก้ไข: เนื่องจากคุณกำลังทำงานกับ JavaScript ในระดับพื้นฐาน มีหลายวิธีที่คุณสามารถบรรลุเป้าหมายของคุณได้ เช่น วิธีที่คุณโพสต์โดยการทำให้เมธอดเป็นแบบ protected และใช้ subclass ในการทดสอบ หรือโดยวิธีการบางอย่างในการทำให้เมธอดเป็น public ชั่วคราวหรือถาวร แต่แทบจะแน่นอนว่าการทำเช่นนี้เป็นเรื่องไม่ฉลาดในทุกกรณี ผมแนะนำอย่างยิ่งให้คุณอ่านลิงก์ต่อไปนี้ซึ่งให้ข้อมูลเพิ่มเติมว่าทำไมการทำเช่นนี้เป็นความคิดที่ไม่ดี และยังให้วิธีแก้ปัญหาที่อาจดีต่อปัญหาที่คุณกำลังเผชิญด้วย: https://enterprisecraftsmanship.com/2017/10/23/unit-testing-private-methods/

คำตอบ #2

วิธีแก้ของฉันคือทำให้ฟังก์ชันเป็น 'protected' และขยายคลาสในคลาสภายในไฟล์ทดสอบ โดยมีฟังก์ชันเหล่านั้นเปิดเผย

ตัวอย่าง :

class ClassToTest {
    protected add(x: number, y: number}: number {
        return x + y;
    }
}

ในไฟล์ทดสอบ:

class PublicClassToTest extends ClassToTest {
    public add(x: number, y: number): number {
        return super.add(x, y);
    }
}

describe('ClassToTest', () => {

    const obj = new PublicClassToTest();

    it('adding 2 numbers', () => {
        // GIVEN x is 6
        const x = 6;

        // AND y is 2
        const y = 2;

        // WHEN we add them
        const result = obj.add(x, y);

        // THEN the result is 8
        expect(result).toBe(8);
    });
});

เป็นฟีเจอร์โบนัส: นี่ไม่เพียงแก้ปัญหาของฉันกับเรื่องนี้ แต่ยังเป็นวิธีดี ๆ ที่ทำให้ฉันเห็นหัวฟังก์ชันของฉันจากภายในไฟล์ทดสอบ โดยไม่จำเป็นต้องสลับไปมาระหว่างไฟล์ทดสอบและคลาสที่ฉันทดสอบ

บทความที่เกี่ยวข้อง