V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Win78
V2EX  ›  Node.js

nodejs 如何在单元测试中 mock path.basename 的运行环境

  •  1
     
  •   Win78 · 2022-07-20 23:38:18 +08:00 · 3457 次点击
    这是一个创建于 868 天前的主题,其中的信息可能已经有所发展或是发生改变。

    nodejs basename 方法会依据运行环境的不同选择不同的实现。

        it('can get basename correctly', () => {
            expect(path.win32.basename('C:\\foo\\bar\\baz.txt')).toBe('baz.txt')
            expect(path.posix.basename('C:\\foo\\bar\\baz.txt')).toBe('C:\\foo\\bar\\baz.txt')
        })
    

    上面的测试用例无论在那个平台执行都是正确的。

        it('can get basename correctly on windows', () => {
            expect(path.basename('C:\\foo\\bar\\baz.txt')).toBe('baz.txt')
        })
    

    上面的测试用例只有在 Windows 系统执行时,才是通过的。问题来了,如何在 mac 上 mock nodejs 的运行环境,指定其为 Windows ,让这个测试用例通过?

    朋友们有没有想法,一直没找到解决思路,困扰好久了。

    6 条回复    2023-02-15 17:01:56 +08:00
    BlackHole1
        1
    BlackHole1  
       2022-07-21 09:05:58 +08:00 via iPhone
    我觉得换个方向可能会更好,即: windows 单测只在 windows 系统中运行。
    你可以封装一个 it.win() 或者 onlyWin(),亦或者在 it 单测上下文中通过 process.platform 来跳过 expect 语句的执行。

    这样一来,你的单测也具备一定的维护性
    Win78
        2
    Win78  
    OP
       2022-07-21 11:33:14 +08:00
    @BlackHole1 谢谢回复,检测 `platform` 变量让特定的测试用例只在特定的平台上运行,这也是一个思路。我感觉这个思路最大问题是我要有 windows 系统才能运行我 windows 相关的单测,现在我手头并没有 windows 设备。

    我有这样的需求是因为业务逻辑涉及到不同文件系统的兼容性,手头上只有 mac ,对 windows 相关逻辑不太放心,想在单元测试中覆盖下。假如能找到合适的 mock 方法,每次运行完测试后,把环境变量还原,单测维护性也还好。
    duan602728596
        3
    duan602728596  
       2022-07-21 13:05:12 +08:00
    可以试着在 docker 、CI\CD pipeline 、Github Actions 中来运行测试用例,这样不同的系统都能够测试到
    zhuweiyou
        4
    zhuweiyou  
       2022-07-21 13:10:48 +08:00
    github actions 配置多个操作系统
    Win78
        5
    Win78  
    OP
       2022-07-21 14:05:34 +08:00
    @duan602728596 @zhuweiyou docker 和 github actions 确实可行,谢谢大家
    Win78
        6
    Win78  
    OP
       2023-02-15 17:01:56 +08:00
    最终,在单元测试里 mock 的方向,我也找到了一个解决方案,使用 `proxyquire` mock `path` 库:
    ```js
    const path = require('path');
    const proxyquire = require('proxyquire');

    const rule = proxyquire('../../../lib/rules/no-index', {
    path: { ...path.win32, '@global': true },
    });
    ```

    ![https://stackoverflow.com/questions/72934150/how-do-i-mock-node-js-running-time-operating-system-in-a-unit-test-for-path-mo]( https://stackoverflow.com/questions/72934150/how-do-i-mock-node-js-running-time-operating-system-in-a-unit-test-for-path-mo)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3549 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 04:46 · PVG 12:46 · LAX 20:46 · JFK 23:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.