【问题标题】:Writing unit test case for third party cli package为第三方cli包编写单元测试用例
【发布时间】:2021-06-04 02:58:07
【问题描述】:

我有一个使用 yargs 构建的基本 CLI 程序。我能够涵盖应用程序中导出函数的测试用例。

正如您在下面看到的,测试覆盖不是从12-18 行完成的。我们如何为 yargs 这样的第三方包编写单元测试覆盖率?

index.js

const yargs = require('yargs');
const { hideBin } = require('yargs/helpers');
const greet = (name) => {
  return `Welcome ${name}`;
};
yargs(hideBin(process.argv)).command(
  'run [name]',
  'print name',
  (yargs) => {
    yargs.positional('name', { describe: 'Your name', type: 'string' });
  },
  (args) => {
    const { name } = args;

    const greetMsg = greet(name);

    console.log(greetMsg);
  }
).argv;

module.exports = { greet };

index.test.js

const { greet } = require('./index')

describe.only('greeting', () => {
  it('greet', async () => {
    const greetMsg = greet('test')

    expect(greetMsg).toBe('Welcome test')
  })
})

测试覆盖率

PASS  ./index.test.js
greeting
  ✓ greet (5 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   63.64 |      100 |   33.33 |   63.64 |                   
index.js  |   63.64 |      100 |   33.33 |   63.64 | 12-18            
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.316 s, estimated 2 s
Ran all test suites.

【问题讨论】:

    标签: node.js unit-testing jestjs mocking yargs


    【解决方案1】:

    您可以使用jest.doMock(moduleName, factory, options) 模拟yargsyargs/helpers 模块。由于模块范围内的yargs 函数将在需要模块时执行。在需要 index.js 模块之前,您需要使用 jest.resetModules() 重置模块注册表 - 每个测试用例的所有必需模块的缓存。

    这对于隔离测试之间本地状态可能发生冲突的模块很有用。

    例如

    index.js:

    const yargs = require('yargs');
    const { hideBin } = require('yargs/helpers');
    
    const greet = (name) => {
      return `Welcome ${name}`;
    };
    yargs(hideBin(process.argv)).command(
      'run [name]',
      'print name',
      (yargs) => {
        yargs.positional('name', { describe: 'Your name', type: 'string' });
      },
      (args) => {
        const { name } = args;
    
        const greetMsg = greet(name);
    
        console.log(greetMsg);
      }
    ).argv;
    
    module.exports = { greet };
    

    index.test.js:

    describe.only('greeting', () => {
      beforeEach(() => {
        jest.resetModules();
      });
      it('greet', () => {
        const { greet } = require('./index');
        const greetMsg = greet('test');
        expect(greetMsg).toBe('Welcome test');
      });
    
      it('should pass', () => {
        jest.doMock('yargs');
        jest.doMock('yargs/helpers');
        const yargs = require('yargs');
        const { hideBin } = require('yargs/helpers');
        const mArgv = {
          command: jest.fn().mockImplementation(function (command, description, builder, handler) {
            builder(this);
            handler({ name: 'teresa teng' });
            return this;
          }),
          argv: {},
          positional: jest.fn(),
        };
        yargs.mockReturnValueOnce(mArgv);
        require('./');
        expect(hideBin).toBeCalled();
        expect(yargs).toBeCalled();
        expect(mArgv.positional).toBeCalledWith('name', { describe: 'Your name', type: 'string' });
      });
    });
    

    测试结果:

     PASS  examples/67830954/index.test.js (7.17 s)
      greeting
        ✓ greet (355 ms)
        ✓ should pass (23 ms)
    
      console.log
        Welcome teresa teng
    
          at examples/67830954/index.js:18:13
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ----------|---------|----------|---------|---------|-------------------
    All files |     100 |      100 |     100 |     100 |                   
     index.js |     100 |      100 |     100 |     100 |                   
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        7.668 s, estimated 8 s
    

    【讨论】:

      猜你喜欢
      • 2013-01-18
      • 1970-01-01
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多