【问题标题】:Mocking Segment Analytics with Jest in TS在 TS 中使用 Jest 模拟段分析
【发布时间】:2021-04-01 08:52:28
【问题描述】:

我正在尝试编写一个单元测试来检查是否调用了 Analytics 的 .track 方法。由于某种原因,测试一直失败,尽管通过 http 调用该函数确实会触发调用。我不确定我是否嘲笑它错了,或者问题可能是什么?

index.ts:

import { Request } from "../types"
import { getSecret } from "../src/secrets"
import Analytics from "analytics-node"

const logger = (req: Request) => {
    const analytics = new Analytics(<string>process.env.WRITE_KEY);
    return analytics.track({
        userId: req.userId
    });
}

export default logger

index.test.ts:

jest.mock('analytics-node');
import { Request } from "../types"
import logger from "./index"
import Analytics from "analytics-node"

const mockAnalytics = new Analytics(process.env.WRITE_KEY = 'test');

describe('Logger tests', () => {
    it(`Should call analytics.track`, () => {
        const request: Request = {
            userId: 23
        }
        return logger(request).then(() => {
            expect(mockAnalytics.track).toHaveBeenCalled()
        });
    });
});

【问题讨论】:

  • 你觉得mockAnalytics与被测代码有什么关系?
  • 我只是将新的 Analytics 保存到一个变量中。 Jest 自动将类方法替换为 jest.fn() 并且我检查了 mockAnalytics.track 确实存在。它只是没有被调用。
  • 但这不是您尝试测试的代码正在使用的实例,那么您为什么期望与它进行交互呢?它也根本不是一个测试替身,它是一个真实的实例。
  • 如果我在返回之前 console.log 它在 index.ts 中,我确实得到了一个笑话。
  • 因为你正在使用jest.mock来模拟模块(所以它不是一个真实的实例,对此感到抱歉),但你在测试中创建的实例是不一定在被测代码中创建的相同实例。当你说测试失败时,究竟发生了什么?您是否有手动模拟,是否已配置为让 track 返回承诺?

标签: javascript typescript unit-testing jestjs tdd


【解决方案1】:

您通过调用jest.mock('analytics-node') 来使用Automatic mock

调用 jest.mock('analytics-node') 会返回一个有用的“自动模拟”,您可以使用它来监视对类构造函数及其所有方法的调用。它用模拟构造函数替换了 ES6 类,并用总是返回 undefined 的模拟函数替换了它的所有方法。方法调用保存在theAutomaticMock.mock.instances[index].methodName.mock.calls

例如

index.ts:

import Analytics from 'analytics-node';

export interface Request {
  userId: string | number;
}

const logger = (req: Request) => {
  const analytics = new Analytics(<string>process.env.WRITE_KEY);
  return analytics.track({
    userId: req.userId,
    anonymousId: 1,
    event: '',
  });
};

export default logger;

index.test.ts:

import logger, { Request } from './';
import Analytics from 'analytics-node';

jest.mock('analytics-node');
const mockAnalytics = Analytics as jest.MockedClass<typeof Analytics>;

describe('Logger tests', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  it(`Should call analytics.track`, () => {
    const WRITE_KEY = process.env.WRITE_KEY;
    process.env.WRITE_KEY = 'test key';
    const request: Request = {
      userId: 23,
    };
    logger(request);
    expect(mockAnalytics).toBeCalledWith('test key');
    expect(mockAnalytics.mock.instances[0].track).toHaveBeenCalled();
    process.env.WRITE_KEY = WRITE_KEY;
  });
});

单元测试结果:

 PASS  examples/65412302/index.test.ts
  Logger tests
    ✓ Should call analytics.track (4 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.954 s

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-07
    • 2020-11-10
    • 2020-06-21
    • 1970-01-01
    • 2021-06-01
    • 2022-11-18
    • 2019-08-19
    • 2018-03-20
    相关资源
    最近更新 更多