简体   繁体   English

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

[英]Mocking es6 module returning factory function (moment.js)

Caveat: I'm new to Jest so bear. 警告:我是Jest的新手所以熊。

I am attempting to test a Vue2.js filter using Jest called DateFilter. 我试图使用名为DateFilter的Jest测试Vue2.js过滤器。 This filter simply applies a date format to a date passed to it. 此过滤器只是将日期格式应用于传递给它的日期。

DateFilter.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;

So, I see three valid unit tests here 所以,我在这里看到三个有效的单元测试

  1. The DateFilter module should export a function DateFilter模块应该导出一个函数

  2. The date filter should initialize moment with the dateValue passed 日期过滤器应该在传递dateValue的情况下初始化时刻

  3. The date filter should call the format method on moment with the dateFormat passed 日期过滤器应该在传递dateFormat时调用format方法

DateFilter.test.js 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
    });
});

Not sure how much in details you want to test something, but I guess that the secret is a good mock of momentjs. 不确定你想要测试一些细节,但我猜这个秘密是对momentjs的好模拟。 Since you just want to test your dateFormatter you can do the next: 由于您只想测试dateFormatter,您可以执行下一步:

First we set the mock to momentjs: 首先我们将模拟设置为momentjs:

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

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

If instead of declaring const, you try to pass the object to jest.fn you will probably get errors that the function was not called, thats because we are going to generate different mocks everytime we call moment instead of having the same mock for all the moment calls. 如果不是声明const,而是尝试将对象传递给jest.fn你可能会得到函数未被调用的错误,那是因为我们每次调用时都会生成不同的模拟,而不是对所有的模拟具有相同的模拟moment电话。

This is a very simple one, you could do a more elaborated moment mock, but I think is not worth it the effort since your functions is simple enough. 这是一个非常简单的,你可以做一个更详细的时刻模拟,但我认为不值得努力,因为你的功能很简单。

Then, I think you have separated unit tests, you could have them in one but some times is better to assert chain of functions separately. 然后,我认为你已经分开了单元测试,你可以将它们合二为一,但有时候最好分别断言函数链。

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)
});

Disclaimer: In the second test it doesn't matter if you expect moment(), moment(mockDate) or moment('Whatever') , since you always mock the same thing you will receive the same format mock back. 免责声明:在第二次测试中,如果你期待moment(), moment(mockDate) or moment('Whatever')并不重要,因为你总是嘲笑同样的事情,你会得到相同的format模拟。

In case you want something more complicated, you will need to create a fixture where you map the date that momentjs have been called, to a new object containing the mocked functions. 如果你想要更复杂的东西,你需要创建一个夹具,在那里你将调用了momentjs的日期映射到包含模拟函数的新对象。 But I believe this is more of a hassle and it is actually better for you to just test that moment has been called and that format has been called. 但我相信这更麻烦,实际上你只需要测试那个时刻已被调用并且该格式已被调用。 Otherwise you are testing to much how the 3rd party library is working. 否则,您正在测试第三方库的工作方式。

Hope this give you some guideline 希望这会给你一些指导

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM