嘲笑的 copyFile 和 stat 函数没有被开玩笑地调用

时间:2021-03-01 20:20:12

标签: javascript node.js typescript jestjs mocking

我正在尝试模拟 fs 模块(fs.promises)中的 copyFile 和 stat 方法。但是没有调用模拟函数,而是通过测试用例调用原始函数。

测试函数代码为:

jest.doMock('fs', () => ({
    promises: {
        copyFile: (src = 'source', dest = 'destination') =>
            jest.fn().mockImplementation(async () => {
                console.log('Inside the mock function in copyFile, please get executed, got frustrated', src, dest);
                return Promise.resolve(false);
            }),
        stat: () =>
            jest.fn().mockImplementation(async () => {
                console.log('Inside the mock function in stat method, please get executed, got frustrated');
                return Promise.resolve(false); // Probably wrong datatype
            }),
    },
}));


describe('Testing implementation', () => {
    const sample = new MainFunction()
    test('Testing', async () => {
        expect(sample.demo()).toEqual(Promise.resolve(true));
    });
});

需要测试的实际代码:

import * as fs from 'fs';
export class MainFunction {
   async demo(): Promise<any> {
    const fileName = 'C:/Users/Desktop/testing-file-dir/';
    const fileName1 = '/destination/'
    let filefound = (await fs.promises.stat(fileName)).isFile();
    await fs.promises.copyFile(fileName,fileName1);
    console.log(filefound, 'inside actual code');
    return Promise.resolve(true);
   }
}

有人可以帮忙解决我哪里出错了吗?我曾想过使用 jest.mock 但它也给出了错误,所以我按照这个链接 https://github.com/facebook/jest/issues/2567 建议尝试 doMock。如果有人知道处理这个模拟函数的更好方法,那就太好了。

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用 jest.mock(moduleName, factory, options),并且您没有正确模拟方法链调用。您应该使用 mockFn.mockReturnThis() 将此上下文返回给调用者。

例如

index.ts

import * as fs from 'fs';

export class MainFunction {
  async demo(): Promise<any> {
    const fileName = 'C:/Users/Desktop/testing-file-dir/';
    const fileName1 = '/destination/';
    let filefound = (await fs.promises.stat(fileName)).isFile();
    await fs.promises.copyFile(fileName, fileName1);
    console.log(filefound, 'inside actual code');
    return Promise.resolve(true);
  }
}

index.test.ts

import { MainFunction } from './';

jest.mock('fs', () => ({
  promises: {
    copyFile: jest.fn().mockImplementation((src = 'source', dest = 'destination') => {
      console.log('Inside the mock function in copyFile, please get executed, got frustrated', src, dest);
      return Promise.resolve(false);
    }),
    stat: jest.fn().mockReturnThis(),
    isFile: jest.fn().mockImplementation(() => {
      console.log('Inside the mock function in stat method, please get executed, got frustrated');
      return Promise.resolve(false);
    }),
  },
}));

describe('Testing implementation', () => {
  const sample = new MainFunction();
  test('Testing', async () => {
    const actual = await sample.demo();
    expect(actual).toBeTruthy();
  });
});

测试结果:

 PASS  examples/66429093/index.test.ts
  Testing implementation
    ✓ Testing (10 ms)

  console.log
    Inside the mock function in stat method, please get executed, got frustrated

      at Object.<anonymous> (examples/66429093/index.test.ts:12:15)

  console.log
    Inside the mock function in copyFile, please get executed, got frustrated C:/Users/Desktop/testing-file-dir/ /destination/

      at Object.<anonymous> (examples/66429093/index.test.ts:7:15)

  console.log
    Promise { false } inside actual code

      at MainFunction.<anonymous> (examples/66429093/index.ts:9:13)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.12 s, estimated 4 s

答案 1 :(得分:0)

根据 slideshowp2 的解决方案,我必须进行此更改以避免出现此 https://github.com/facebook/jest/issues/2567 中所述的错误。

实际文件保持不变,而测试文件更改为:

jest.mock('fs', () => {
    const originalModule = jest.requireActual('fs'); // so as to not override other functions apart from below mentioned one's
    return Object.assign({ __esModule: true }, originalModule, {
        promises: {
            copyFile: jest.fn().mockImplementation((src, dest) => {
                // src, dest are parameters passed in copyFile from src to destination
                let source = 'some source'; // sample source file
                if (source === src) {
                    return true;
                } else {
                    throw Error;
                }
            }),
            stat: jest.fn().mockReturnThis(),
            isFile: jest
                .fn()
                .mockImplementationOnce(() => { // I had series of test so for first one I wanted false hence this part, else we can remove this and directly use .mockImplementation()
                    return false;
                })
                .mockImplementation(() => {
                    return true;
                }),
        },
    });
});
describe('Testing implementation', () => {
    const sample = new MainFunction();
    test('Testing', async () => {
    const actual = await sample.demo();
    expect(actual).toBeTruthy();
   });
});