【问题标题】:Mocked copyFile and stat function not getting called in jest嘲笑的 copyFile 和 stat 函数没有被开玩笑地调用
【发布时间】:2021-03-01 20:20:12
【问题描述】:

我正在尝试从 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。如果有人知道更好的方法来处理这个模拟函数,那就太好了。

谢谢!

【问题讨论】:

    标签: javascript node.js typescript jestjs mocking


    【解决方案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
    

    【讨论】:

    • 谢谢,是的,我对实现部分感到困惑。这确实有帮助,但我仍然遇到类似于我在尝试使用 jest.mock 时在问题中指出的 github url 的问题,但当我在 mock 中使用 Object.assign 时它仍然有效。
    【解决方案2】:

    根据 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();
       });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-20
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 1970-01-01
      • 2019-01-02
      相关资源
      最近更新 更多