Tìm kiếm trang web

jestjs - Không thể giả lập fs với jest sử dụng typescript - Thuộc tính 'mockReturnValue' không tồn tại trên kiểu


Vấn đề:

Có ai giúp tôi tìm cách giả lập fs với jest sử dụng typescript không? Tôi đã thử vài cách, và đây là cách chính:

Tôi đang cố gắng sử dụng jest để giả lập 'fs', nhưng dường như tôi không thể khiến jest tự động giả lập thư viện 'fs' trong Typescript.

Đây là mã của tôi:

import fs from 'fs';

jest.mock('fs');

describe('helloWorld.ts', () => {
  it('foobar', () => {

    fs.readdirSync.mockReturnValue(['foo.js', 'bar.js']);
  })
});

Typescript báo cho tôi 'Thuộc tính 'mockReturnValue' không tồn tại trên kiểu...'

Môi trường:

Node v14.15.1
Typescript: "^4.0.3"
VS Code Typescript: 4.1.2

Liên quan đến vấn đề này, tôi đã thử điều này với spyOn và nó thất bại:

Tôi đã cố gắng sử dụng cái này nhưng cũng không thể làm spyOn hoạt động (tham khảo: jest typescript property mock không tồn tại trên kiểu)

import fs from 'fs';

describe('helloWorld.ts', () => {
  it('foobar', () => {
    jest.spyOn(fs, 'readdirSync').mockImplementation(() => {
      return ['foo.js', 'bar.js'];
    });
    console.log(fs.readdirSync('.'));
  });
});

Mã này bị lỗi với lỗi TypeScript TS2345:

Argument of type '() => string[]' is not assignable to parameter of type '(path: PathLike, options: BaseEncodingOptions & { withFileTypes: true; }) => Dirent[]'.
      Type 'string[]' is not assignable to type 'Dirent[]'.
        Type 'string' is not assignable to type 'Dirent'.

Tham khảo liên quan:

  • Điều này có vẻ liên quan, nhưng tôi cảm thấy có một giải pháp tốt hơn: Giả lập module 'fs' trong jest
  • Jest có một vấn đề ở đây cho thấy việc giả lập 'fs' nên hoạt động khi được giả lập rõ ràng với jest.mock('fs') https://github.com/facebook/jest/issues/2258

Câu trả lời #1

Trình biên dịch TypeScript không biết gì về fs là một bản giả lập.

Bạn có thể cho nó biết điều này bằng cách sử dụng khai báo kiểu:

(<jest.Mock>fs.readdirSync).mockReturnValue(...);

Việc này trở nên nhàm chán khi phải làm mỗi lần bạn sử dụng các hàm giả lập được nhập từ mô-đun fs. Để mọi thứ đơn giản hơn, bạn có thể khai báo một biến có kiểu là module mock, khởi tạo nó với fs và sử dụng nó thay cho fs trong các bài kiểm tra:

import fs from 'fs';

jest.mock('fs');

const mockFS: jest.Mocked<typeof fs> = <jest.Mocked<typeof fs>>fs;

describe('helloWorld.ts', () => {
  it('foobar', () => {

    mockFS.readdirSync.mockReturnValue(['foo.js', 'bar.js']);
  });
});

Bài viết liên quan