node.js - TSNode + Mocha: เพิกเฉยต่อข้อผิดพลาดของ TypeScript (ทำให้คอมไพเลอร์สร้างโค้ดแม้มีข้อผิดพลาดและทำให้ TSNode รันโค้ดที่ถูกสร้าง)
ในโค้ดด้านล่าง แม้ว่าฟังก์ชัน test2 จะไม่ถูกต้อง แต่ก็ไม่ควรมีผลต่อการทดสอบฟังก์ชัน test1:
export function test1(): boolean {
return true;
}
export function test2(): number {
return "1";
}
ทดสอบ :
import { assert as Assert } from "chai";
import { test1 } from "./example";
describe("Example", (): void => {
it("Example", (): void => {
Assert.isTrue(test1());
});
});
อย่างไรก็ตาม Mocha ที่รันโดย TSNode จะล้มเหลว:
TSError: ⨯ Unable to compile TypeScript:
Source/ProjectBuilder/example.ts(6,3): error TS2322: Type '"1"' is not assignable to type 'number'.
เป็นไปได้ไหมที่จะบังคับให้ TSNode ทำการทดสอบข้างต้นให้เสร็จ? TypeScript มีตัวเลือก noEmitOnError...
mocharc.yaml ของฉัน:
extension:
- ts
spec: "**/*.test.ts"
require:
- ts-node/register
- tsconfig-paths/register
ทำไมฉันถึงต้องการมัน
ตาม สถาปัตยกรรมสะอาด "กฎทางธุรกิจต้องไม่พึ่งพาสิ่งใด ๆ และต้องสามารถทดสอบได้" แต่แม้ว่ากฎทางธุรกิจจะไม่พึ่งพา views, controllers ฯลฯ เราก็ไม่สามารถทดสอบมันได้หากมีข้อผิดพลาดใน views, controllers ฯลฯ อยู่
เมื่อฉันแก้ไขตรรกะทางธุรกิจในแอปพลิเคชันของฉัน สิ่งที่ขึ้นอยู่กับมันทั้งหมดจะกลายเป็นโมฆะ สมมติว่าในเอนทิตีของฉันในตรรกะธุรกิจ type User { name: string; age: number } ได้ถูกเปลี่ยนเป็น type User { fullName: string; age: string; } สิ่งที่ขึ้นอยู่กับตรรกะธุรกิจทั้งหมด (มุมมอง ตัวควบคุม ผู้เสนอ ฯลฯ) จะกลายเป็นโมฆะ - ฉันจึงจำเป็นต้องแก้ไขมันด้วยตามการปรับปรุงตรรกะธุรกิจ
// In business rules:
type User = {
ID: number;
fullName: string;
age: string; // in past - number
}
// In controller:
class UserProfileController {
// ...
// All what comes from input field is string ↓
private onClickChangeUserAge(inputtedUserAge: string) {
// This expression obeys to previous version of business rules!
this.targetUser.age = Number(inputtedUserAge);
// TypeScript will emit type error, when I try to test business rules,
// however business rules does not depend on controller.
}
}
อย่างไรก็ตาม ในแอปพลิเคชันขนาดใหญ่ การแก้ไขเหล่านี้อาจใช้เวลาหลายวัน หลายสัปดาห์ หรือหลายเดือน เราจะได้รับข้อเสนอแนะที่พิสูจน์ได้อย่างไรว่าอย่างน้อยตรรกะทางธุรกิจก็ทำงานอย่างถูกต้องและเราอยู่ในเส้นทางที่ถูกต้อง?
คำตอบ #1
มันไม่มีเหตุผลเลยที่คุณจะขอให้ Typescript ไม่สนใจประเภท สิ่งที่คุณกำลังอธิบายนั้นคล้ายกับการขอเครื่องคิดเลขที่ยืนยันว่า 2 + 2=5 เพียงชั่วคราว เพราะในที่สุดคุณจะขอให้ 2 + 3=5 แต่สิ่งนั้นอาจใช้เวลานานมาก
สมมติฐานในคำถามของคุณคือ number และ string มีความเข้ากันได้เพียงพอที่ตรรกะทางธุรกิจของคุณจะถูกต้องไม่ว่าจะ test2 คืนค่า 1 หรือ "1" ซึ่งนี่ไม่เป็นความจริง: ยกตัวอย่างเช่น 1 + 1 == 2, "1" + 1 == "11", และ "1" - 1 == 0 ขึ้นอยู่กับว่าอันไหนใช้กับกรณีของคุณ การไม่สนใจชนิดข้อมูลอาจทำให้คุณทดสอบตรรกะทางธุรกิจได้ หรืออาจทำให้คุณมั่นใจโดยผิดพลาดในระบบที่เสียหายก็ได้ ผมขอสรุปอย่างคร่าวๆ ว่าโดยทั่วไปชนิดข้อมูลถือเป็นส่วนหนึ่งของตรรกะทางธุรกิจที่คุณพยายามตรวจสอบ--โมเดลข้อมูลจะถือเป็นอะไร หากไม่ใช่ตรรกะทางธุรกิจ?
แทนที่จะเป็นเช่นนั้น สิ่งที่คุณกำลังอธิบายคือ การย้ายข้อมูลอย่างค่อยเป็นค่อยไป ซึ่งกฎของธุรกิจจะทำให้แน่ใจว่า test2 คืนค่า string | number โดยการอธิบายการย้ายข้อมูลอย่างแม่นยำในระบบประเภท คุณอาจสามารถยืนยันได้ว่าตรรกะทางธุรกิจถูกต้อง--หากเป็นจริงตลอดการย้ายข้อมูลของคุณ--และยังสามารถให้ประเภทที่คุณสามารถใช้ได้เฉพาะจากโมดูลและจุดเรียกบางจุดที่สามารถปรับให้เข้มงวดขึ้นเมื่อคุณทำการย้ายข้อมูลเสร็จ.
คำตอบ #2
type User = {
ID: number;
fullName: string;
age: string | number
}
คุณสามารถระบุทั้งสองประเภทเพื่อให้ง่ายต่อการย้ายและไม่ต้องใช้ //@ts-ignore ทุกที่
นี่จะเพิ่มคำแนะนำที่ถูกต้องทุกที่ เช่น:
