模拟es6模块返回工厂功能(moment.js)

时间:2018-06-20 19:53:59

标签: javascript unit-testing vue.js vuejs2 jestjs

注意:我是Jest的新手,所以请忍受。

我正在尝试使用名为DateFilter的Jest测试Vue2.js过滤器。该过滤器只是将日期格式应用于传递给它的日期。

DateFilter.js

import Vue from 'vue';
import moment from 'moment';

const dateFormatter = (dateValue, dateFormat) => {
    return moment(dateValue).format(dateFormat);
};

Vue.filter('date', dateFormatter);

export default dateFormatter;

所以,我在这里看到三个有效的单元测试

  1. DateFilter模块应导出一个函数

  2. 日期过滤器应使用传递的dateValue初始化时刻

  3. 日期过滤器应在通过dateFormat的时刻调用format方法

DateFilter.test.js

import moment from 'moment';
import DateFilter from './DateFilter';

describe('DateFilter', () => {
    it('should exist', () => {
        expect(DateFilter).toBeDefined();
        expect(typeof DateFilter).toBe('function');
    });

    it('should moment.format with the dateValue and dateFormat passed.', () => {
        // Here I get lost in how to spyOn moment function and the .format function
        const mockDateFormat = `dateFormat-${Math.random()}`;
        const mockDate = `mockDate-${Math.random()}`;
        jest.mock('moment', () => {
            return { format: jest.fn() }
        });
        // expect moment to have been called with mockDate
        // expect moment(mockDate) to have been called with mockDateFormat
    });
});

1 个答案:

答案 0 :(得分:2)

不确定要测试的细节多少,但是我想这个秘密很好地模拟了momentjs。由于您只想测试dateFormatter,因此可以执行下一个操作:

首先,我们将模拟设置为momentjs:

jest.mock('moment', () => {
    const momentMock = { format: jest.fn() }

    return jest.fn(() => momentMock);
});

如果您尝试将对象传递给jest.fn而不是声明const,则可能会得到未调用该函数的错误,那是因为我们每次调用矩时都会生成不同的模拟,而不是使用所有moment调用都使用相同的模拟。

这是一个非常简单的示例,您可以进行更详细的时刻模拟,但是由于您的函数足够简单,因此我认为这样做是不值得的。

然后,我认为您已经将单元测试分开了,可以将它们组合在一起,但有时最好单独声明功能链。

it('calls moment with the dateValue passed.', () => {
    const mockDateFormat = `dateFormat-${Math.random()}`;
    const mockDate = `mockDate-${Math.random()}`;

    dateFormatter(mockDate, mockDateFormat);

    expect(moment).toHaveBeenCalledWith(mockDate)
});
it('calls format with the dateFormat passed.', () => {
    const mockDateFormat = `dateFormat-${Math.random()}`;
    const mockDate = `mockDate-${Math.random()}`;

    dateFormatter(mockDate, mockDateFormat);

    expect(moment(mockDate).format).toHaveBeenCalledWith(mockDateFormat)
});

免责声明:在第二项测试中,您是否期望moment(), moment(mockDate) or moment('Whatever')都无关紧要,因为您总是模拟相同的事物,因此您将收到相同的format模拟。

如果您想要更复杂的东西,则需要创建一个固定装置,在其中将调用momentjs的日期映射到包含模拟函数的新对象。但是我相信这比较麻烦,实际上,让您测试一下是否已调用该时刻以及是否已调用该格式实际上更好。否则,您需要测试第三方库的工作方式。

希望这会给您一些指导