【问题标题】:How to unit test a javascript object with value?如何对具有值的 javascript 对象进行单元测试?
【发布时间】:2021-09-23 11:30:59
【问题描述】:

我有一个 js 文件,我在其中读取了一些值并将结果加载到变量中。我得到的好处是我不必每次需要时都从文件中读取。我可以简单地导入对象并使用它。

但是我不知道如何为它编写单元测试。

    const fs = require('fs');


const read_file = (path) => {
  try {
    const data = fs.readFileSync(path, 'utf8');
    return data;
  } catch (err) {
    console.error('Error in read_file', err);
    throw err;
  }
};

const getSecret = secretName => {
  try {
    return read_file(`/etc/secrets/${secretName}.txt`);
  } catch (err){
    throw err;
  }
};

const secretConfig = {
  kafka_keystore_password: getSecret('kafka_keystore_password')
};

module.exports = secretConfig;

我用 jest 写测试用例。

我已经尝试过类似的方法,但对象仍然解析为未定义。

const secretConfig = require('./secret');
const fs = require('fs');
jest.mock('fs');
fs.readFileSync.mockReturnValue('randomPrivateKey');


 

describe('secret read files', () => {
    
  it('should read secret from file', async () => {
    const secretMessage = secretConfig.kafka_keystore_password;
    expect(secretMessage).toEqual('randomPrivateKey');

  })

})

秘密读取文件 › 应该从文件中读取秘密

expect(received).toEqual(expected) // deep equality

Expected: "randomPrivateKey"
Received: undefined

  18 |     const secretMessage = secretConfig.kafka_keystore_password;
  19 |     //expect(fs.readFileSync).toHaveBeenCalled();
> 20 |     expect(secretMessage).toEqual('randomPrivateKey');

【问题讨论】:

    标签: javascript unit-testing jestjs fs ts-jest


    【解决方案1】:

    你的测试是正确的。问题是您需要在require 之前模拟./secret 模块,因为getSecret 方法将在需要模块时立即执行。此时,fs.readFileSync 尚未被赋予模拟值。

    const fs = require('fs');
    fs.readFileSync.mockReturnValue('randomPrivateKey');
    const secretConfig = require('./secret');
    
    jest.mock('fs');
    
    describe('secret read files', () => {
      it('should read secret from file', async () => {
        const secretMessage = secretConfig.kafka_keystore_password;
        expect(secretMessage).toEqual('randomPrivateKey');
      });
    });
    

    测试结果:

    > jest "-o" "--coverage"
    
     PASS  examples/69283738/secret.test.js (7.265 s)
      secret read files
        ✓ should read secret from file (2 ms)
    
    -----------|---------|----------|---------|---------|-------------------
    File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -----------|---------|----------|---------|---------|-------------------
    All files  |   76.92 |      100 |     100 |   76.92 |                   
     secret.js |   76.92 |      100 |     100 |   76.92 | 8-9,17            
    -----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        7.794 s
    

    【讨论】:

    • 快速问题:变量 secretConfig.kafka_keystore_password 将在内存中可用多长时间?该对象的范围是什么?此应用程序是带有 nodejs 环境的 expressJS 控制器
    • @amarnathharish 此变量保留在内存中,直到 nodejs 进程退出。应用程序是快速 Web 服务器还是通用脚本程序。对于测试,它是一个 JS 脚本。测试运行器会收集要测试的用例,程序会执行一次,不会像web服务器那样长时间运行。我不确定您所说的“该对象的范围是什么”是什么意思
    • 如果我理解正确,一旦节点应用程序在第一个 require/import 语句启动时,只会读取文件,对于后续请求,对象 secretConfig 将具有值“randomwPrivateKey”?即使对象 secretConfig 的范围更改为 'let' 而不是 'const' ??另外,如果我必须在同一个 secre.test.js 文件中再写一个测试用例,它仍然会有值“randomPrivatekey”吗?那我该如何测试错误场景呢?
    • @amarnathharish require.cache,模块在需要时缓存在此对象中。对于这种情况,您应该使用jest.doMock()jest.resetModules() 来清除每个测试用例的模块缓存。你可以先试试,有问题再问。
    猜你喜欢
    • 2019-08-13
    • 2010-09-11
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 2014-05-21
    • 1970-01-01
    • 2020-02-05
    相关资源
    最近更新 更多