10

I have a react/typescript project, using jest, where I have a custom matcher like:

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 };
            }
        };
    }
};

which I reference in my tests by doing inside the describe function:

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

And use like this in it functions:

expect(localValue).toBeTheSameAsRemote(remoteValue);

Tests run properly, but typescript compiler does not recognize the matcher, which makes sense cuz I haven't defined it anywhere in the types system

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

What I have found so far relates to extending the namespace for jasmine and/or jest, e.g.

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

which hasn't worked for me.

Do you have any idea?

4

1 回答 1

10

尝试这个:

以下文件声明了实际实现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没有显式导入(它是全局导入)。
  • 函数的签名在 TypeScripttoBeTheSameAsRemote内部和内部并不相同。expect.extend
于 2020-01-13T22:53:57.143 回答