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

ประเภท - จะทำให้ TypeScript รู้จัก matcher ของ Jest ที่กำหนดเองได้อย่างไร?


ฉันมีโปรเจค React/TypeScript ใช้ Jest ซึ่งฉันมี matcher แบบกำหนดเองเช่น:

export const MyCustomMatchers = {
    toBeTheSameAsRemote: function(_util: any, _customEqualityTesters: any) {
        return {
            compare: function(actual: Brand, expected: RemoteBrand) {
                const pass: boolean = attributesMatch(actual, expected);
                const message: string = pass
                    ? 'Local matches Remote'
                    : 'Local does not match Remote';

                return { pass, message: () => message };
            }
        };
    }
};

ซึ่งฉันอ้างอิงในการทดสอบของฉันโดยทำภายในฟังก์ชัน describe:

beforeEach(() => {
  jasmine.addMatchers(MyCustomMatchers);
});

และใช้แบบนี้ในฟังก์ชัน it:

expect(localValue).toBeTheSameAsRemote(remoteValue);

การทดสอบทำงานได้ถูกต้อง แต่คอมไพเลอร์ของ TypeScript ไม่รู้จัก matcher ซึ่งก็สมเหตุสมผลเพราะฉันยังไม่ได้กำหนดมันไว้ที่ใดในระบบประเภท

Property 'toBeTheSameAsRemote' does not exist on type 'JestMatchersShape<Matchers<void, MyType[]>, Matchers<Promise<void>, MyType[]>>'.ts(2339)

สิ่งที่ฉันค้นพบจนถึงตอนนี้เกี่ยวข้องกับการขยาย namespace สำหรับ jasmine และ/หรือ jest เช่น

declare namespace jasmine {
    interface Matchers {
        toBeTheSameAsRemote(remote: any): any;
    }
}

ซึ่งใช้ไม่ได้ผลสำหรับฉัน

คุณมีความคิดอะไรไหม?

คำตอบ #1

ลองอันนี้:

ไฟล์ต่อไปนี้ประกาศทั้งการใช้งานจริง expect.extend และการประกาศ TypeScript ด้วย

custom-matcher.ts:

declare global {
  namespace jest {
    interface Matchers<R> {
        toBeTheSameAsRemote: (expected: string) => CustomMatcherResult;
    }
  }
}

expect.extend({
    /**
     * Notice that this implementation has 2 arguments, but the implementation inside the Matchers only has 1
     */
    toBeTheSameAsRemote(
    received: string,
    expected: string
  ) {
    return {
      pass: false,
      message: "A GraphQl error was expected"
    };
  }
});

// I am exporting nothing just so we can import this file
export default undefined;

ตอนนี้ บนไฟล์ทดสอบของคุณ ให้นำเข้ามอดูลข้างต้น

actual-test.ts:

// importing the custom matcher file is important
import "../../testing/custom-matchers/custom-matcher";

describe("something", () => {
   it("should work", () => {
       expect(localValue).toBeTheSameAsRemote(remoteValue);
   });
});

บันทึก:

  • expect.extend จะถูกเรียกโดยอัตโนมัติจากการนำเข้า ไม่มีความจำเป็นต้องเรียก expect.extend ในทุกไฟล์ทดสอบ
  • declare global จำเป็นเพราะ jest ไม่ได้ถูกนำเข้าอย่างชัดเจน (มันเป็นการนำเข้าระดับสากล)
  • ลายเซ็นของฟังก์ชัน toBeTheSameAsRemote ไม่เหมือนกันภายใน expect.extend และบน TypeScript

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