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