jestjs - Hur får man en Jest-anpassad matcher att fungera i TypeScript?


Jag har regelbundet enhetstester där jag behöver jämföra två moment-objekt. Jag skulle använda moments inbyggda funktion moment.isSame(moment) för att jämföra dem. Detta innebär dock att mitt påstående kommer att se ut så här:

expect(moment1.isSame(moment2)).toBeTrue();

Jag gillade det inte riktigt, särskilt eftersom felmeddelandet kommer att vara mindre informativt. Därför ville jag skriva en egen jest-matcher "toBeSameMoment". Följande kod verkar åtminstone kompilera:

import moment from "moment";

declare global {
  namespace jest {
    interface MomentMatchers extends Matchers<moment.Moment> {
      toBeSameMoment: (expected: moment.Moment) => CustomMatcherResult;
    }
  }
}

expect.extend({
  toBeSameMoment(received: moment.Moment, expected: moment.Moment): jest.CustomMatcherResult {
    const pass: boolean = received.isSame(expected);
    const message: () => string = () => pass ? "" : `Received moment (${received.toISOString()}) is not the same as expected (${expected.toISOString()})`;

    return {
      message,
      pass,
    };
  },
});

Dock kan jag inte riktigt få det att fungera i mitt enhetstest... När jag försöker följande testkod:

import moment from "moment";
import "../jest-matchers/moment";

describe("Moment matcher", () => {

  test("should fail", () => {
    const moment1 = moment.utc();
    const moment2 = moment();

    expect(moment1).toBeSameMoment(moment2);
  });

});

...då får jag följande fel:

error TS2339: Property 'toBeSameMoment' does not exist on type 'JestMatchersShape<Matchers<void, Moment>, Matchers<Promise<void>, Moment>>'.

Jag förstår inte riktigt det här felet. Till exempel, vad är void-typen som det här refererar till? Jag har försökt googla om det, men hittade egentligen ingen bra guide eller så. Jag tog dock notis om den här frågan: Hur man låter TypeScript-kompilatorn känna till jest-anpassade matchers?, som verkar vara i princip en duplicering, men tydligen inte tillräckligt tydlig än.

Jag har Jest-typer inkluderade i min tsconfig

Svar #1

Den andra frågan och svaret som du länkat till var korrekta, och du kan också hitta ett mycket kortfattat exempel på hur man utökar jest i denna github-kommentar om react-testing-library.

För att implementera deras lösning för din kod, ändra bara:

declare global {
  namespace jest {
    interface MomentMatchers extends Matchers<moment.Moment> {
      toBeSameMoment: (expected: moment.Moment) => CustomMatcherResult;
    }
  }
}

Till :

declare global {
  namespace jest {
    interface Matchers<R> {
      toBeSameMoment(expected: moment.Moment): CustomMatcherResult;
    }
  }
}

Relaterade artiklar