【问题标题】:Mocking nested functions with jest用笑话模拟嵌套函数
【发布时间】:2021-10-18 15:44:01
【问题描述】:

我有这个代码;

import { initRepo, getOrganisationsRepo } from "Repositories";
import logger from "Logger";

export const getOrganisations = async (event) => {
  try {
    await initRepo();
    const repo = await getOrganisationsRepo();
    const data = await repo.getOrganisations();

    // 200: Response is an array & is not empty
    if (Array.isArray(data) && data.length)
      return { statusCode: 200, body: JSON.stringify(data) };

    // 404: Response is an array and is empty
    if (Array.isArray(data) && !data.length) return { statusCode: 404 };

    return { statusCode: 400 };
  } catch (error) {
    const errorMessage = error?.message || "error fetching organisations";
    logger.error({ event: "org_get_failed" }, errorMessage);

    return { statusCode: 400, body: errorMessage };
  }
};

我想用 jest 模拟以下调用,因为这是我不想在这里测试的数据库逻辑。

await initRepo();
const repo = await getOrganisationsRepo();
const data = await repo.getOrganisations();

我想模拟repo.getOrganisations();的返回值

我不太确定该怎么做。我可以模拟getOrganisationsRepo,但我不确定如何模拟repo.getOrganisations() 的返回值

这几乎是模拟所获得的,这些工作,我可以测试这两个函数是否被调用过一次,等等。

jest.mock("Repositories");
mockRepositories.initRepo.mockImplementation(() => Promise.resolve());
mockRepositories.getOrganisationsRepo.mockImplementation(() =>
  Promise.resolve()
);

【问题讨论】:

    标签: node.js unit-testing jestjs mocking


    【解决方案1】:

    jest.mock() 将模拟 Repositories 模块,其导出的函数将被自动模拟。这意味着第二个模拟工厂函数是可选的。由于initRepo 函数已被模拟并且没有解析值,因此您无需再次模拟它。我们应该专注于模拟 getOrganisationsRepo 函数及其解析/拒绝值。

    例如

    getOrganisations.js:

    import { initRepo, getOrganisationsRepo } from './Repositories';
    
    export const getOrganisations = async (event) => {
      try {
        await initRepo();
        const repo = await getOrganisationsRepo();
        const data = await repo.getOrganisations();
    
        // 200: Response is an array & is not empty
        if (Array.isArray(data) && data.length) return { statusCode: 200, body: JSON.stringify(data) };
    
        // 404: Response is an array and is empty
        if (Array.isArray(data) && !data.length) return { statusCode: 404 };
    
        return { statusCode: 400 };
      } catch (error) {
        const errorMessage = error?.message || 'error fetching organisations';
    
        return { statusCode: 400, body: errorMessage };
      }
    };
    

    Repositories.js:

    export async function initRepo() {
      console.log('initRepo real implementation');
    }
    export async function getOrganisationsRepo() {
      console.log('getOrganisationsRepo real implementation');
    }
    

    getOrganisations.test.js:

    import { getOrganisations } from './getOrganisations';
    import { getOrganisationsRepo } from './Repositories';
    
    jest.mock('./Repositories');
    
    describe('68805379', () => {
      afterAll(() => {
        jest.resetAllMocks();
      });
      test('should return array data', async () => {
        const repo = {
          getOrganisations: jest.fn().mockResolvedValueOnce([{ id: 1 }]),
        };
        getOrganisationsRepo.mockResolvedValueOnce(repo);
        const actual = await getOrganisations();
        expect(actual).toEqual({ statusCode: 200, body: JSON.stringify([{ id: 1 }]) });
        expect(getOrganisationsRepo).toBeCalledTimes(1);
        expect(repo.getOrganisations).toBeCalledTimes(1);
      });
    });
    

    测试结果:

     PASS  examples/68805379/getOrganisations.test.js (9.919 s)
      68805379
        ✓ should return array data (5 ms)
    
    ---------------------|---------|----------|---------|---------|-------------------
    File                 | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ---------------------|---------|----------|---------|---------|-------------------
    All files            |   63.16 |    21.43 |      50 |      60 |                   
     Repositories.js     |      50 |      100 |       0 |      50 | 2,5               
     getOrganisations.js |   66.67 |    21.43 |     100 |   63.64 | 13-19             
    ---------------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        11.002 s
    

    附:我在使用jest.mock()时使用相对路径./Repositories而不是模块别名,如果你已经设置了模块别名,那么你应该使用模块别名作为jest.mock()的模块名。

    【讨论】:

    • 这绝对是一种享受。谢谢。
    猜你喜欢
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2019-07-15
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多