Jest.js 扩展全局公开的第三方模块

apeeds0o  于 2023-08-01  发布在  Jest
关注(0)|答案(4)|浏览(134)

我正在尝试添加一个自定义匹配到Jest在Typescript。这工作正常,但是我不能让Typescript识别扩展的Matchers
myMatcher.ts

export default function myMatcher (this: jest.MatcherUtils, received: any, expected: any): { pass: boolean; message (): string; } {
  const pass = received === expected;
  return {
    pass: pass,
    message: () => `expected ${pass ? '!' : '='}==`,
  }
}

字符串
myMatcher.d.ts

declare namespace jest {
  interface Matchers {
    myMatcher (expected: any): boolean;
  }
}


someTest.ts

import myMatcher from './myMatcher';

expect.extend({
  myMatcher,
})

it('should work', () => {
  expect('str').myMatcher('str');
})


tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist/",
    "moduleResolution": "node",
    "module": "es6",
    "target": "es5",
    "lib": [
      "es7",
      "dom"
    ]
  },
  "types": [
    "jest"
  ],
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "dist",
    "doc",
    "**/__mocks__/*",
    "**/__tests__/*"
  ]
}


在sometTests.ts中,我得到错误

error TS2339: Property 'myMatcher' does not exist on type 'Matchers'


我已经通读了微软的文档好几遍了,但是我不知道如何用全局可用的类型(不导出)进行命名空间合并。
将它放在jest的index.d.ts中可以很好地工作,但对于快速变化的代码库和由多方扩展的类来说,这不是一个好的解决方案。

p4tfgftt

p4tfgftt1#

好的,这里有几个问题
当源文件(.ts.tsx)文件和声明文件(.d.ts)文件都是模块解析的候选文件时,就像这里的情况一样,编译器将解析源文件。
您可能有两个文件,因为您要导出一个值,同时还要修改全局对象jest的类型。但是,您不需要两个文件,因为TypeScript有一个特定的构造,用于从模块中扩展全局范围。也就是说,您只需要以下.ts文件

myMatcher.ts

// use declare global within a module to introduce or augment a global declaration.
declare global {
  namespace jest {
    interface Matchers {
      myMatcher: typeof myMatcher;
    }
  }
}
export default function myMatcher<T>(this: jest.MatcherUtils, received: T, expected: T) {
  const pass = received === expected;
  return {
    pass,
    message: () => 'expected' + pass ? '===' : '!==';
  };
}

字符串
也就是说,如果你有这样的情况,在同一个文件中执行全局 mutation 和全局类型 augmentation 是一个很好的做法。鉴于此,我会考虑将其改写如下

myMatcher.ts

// ensure this is parsed as a module.
export {}

declare global {
  namespace jest {
    interface Matchers {
      myMatcher: typeof myMatcher;
    }
  }
}
function myMatcher<T>(this: jest.MatcherUtils, received: T, expected: T) {
  const pass = received === expected;
  return {
    pass,
    message: () => 'expected' + pass ? '===' : '!==';
  };
}

expect.extend({
  myMatcher
});

someTest.ts

import './myMatcher';

it('should work', () => {
  expect('str').myMatcher('str');
});

cpjpxq1n

cpjpxq1n2#

一个简单的方法是:

customMatchers.ts

declare global {
    namespace jest {
        interface Matchers<R> {
            // add any of your custom matchers here
            toBeDivisibleBy: (argument: number) => {};
        }
    }
}

// this will extend the expect with a custom matcher
expect.extend({
    toBeDivisibleBy(received: number, argument: number) {
        const pass = received % argument === 0;
        if (pass) {
            return {
                message: () => `expected ${received} not to be divisible by ${argument}`,
                pass: true
            };
        } else {
            return {
                message: () => `expected ${received} to be divisible by ${argument}`,
                pass: false
            };
        }
    }
});

字符串

我的规格ts

import "path/to/customMatchers";

test('even and odd numbers', () => {
   expect(100).toBeDivisibleBy(2);
   expect(101).not.toBeDivisibleBy(2);
});

dfuffjeb

dfuffjeb3#

@AluanHaddad的回答几乎是正确的,没有几种类型。这个可以用:

export {};

declare global {
  namespace jest {
    interface Matchers<R> {
      myMatcher: (received: string) => R;
    }
  }
}

function myMatcher<T>(this: jest.MatcherUtils, received: string, expected: string): jest.CustomMatcherResult {
  const pass = received === expected;
  return {
    pass,
    message: (): string => `expected ${received} to be ${expected}`,
  }
}

expect.extend({
  myMatcher,
});

字符串
有关真实世界的示例,请参见https://github.com/Quantum-Game/quantum-tensors/blob/master/tests/customMatchers.ts(测试实际通过:https://travis-ci.com/Quantum-Game/quantum-tensors)。

e0bqpujr

e0bqpujr4#

"@types/testing-library__jest-dom"添加到tsconfig.json中的types,为我解决了这个问题

// tsconfig.json

"types": [
      "node",
      "jest",
      "@types/testing-library__jest-dom"
    ],

字符串
属性'toBeInTheDocument'在类型'Matchers '上不存在

相关问题