简体   繁体   English

React和Jest模拟模块

[英]React and jest mock module

I am creating an application in which I use redux and node-fetch for remote data fetching. 我正在创建一个应用程序,在其中我使用redux和node-fetch进行远程数据获取。

I want to test the fact that I am well calling the fetch function with a good parameter. 我想测试一个事实,那就是我很好地调用了具有良好参数的fetch函数。

This way, I am using jest.mock and jasmine.createSpy methods : 这样,我正在使用jest.mock和jasmine.createSpy方法:

it('should have called the fetch method with URL constant', () => {
            const spy = jasmine.createSpy('nodeFetch');
            spy.and.callFake(() => new Promise(resolve => resolve('null')));
            const mock = jest.mock('node-fetch', spy);
            const slug = 'slug';
            actionHandler[FETCH_REMOTE](slug);
            expect(spy).toHaveBeenCalledWith(Constants.URL + slug);
        });

Here's the function that I m trying to test : 这是我要测试的功能:

[FETCH_REMOTE]: slug => {
        return async dispatch => {
            dispatch(loading());
            console.log(fetch()); // Displays the default fetch promise result
            await fetch(Constants.URL + slug);
            addLocal();
        };
    }

AS you can see, I am trying to log the console.log(fetch()) behavior, and I am having the default promise to resolve given by node-fetch, and not the that I've mock with Jest and spied with jasmine. 如您所见,我正在尝试记录console.log(fetch())行为,并且我具有默认承诺来解决node-fetch给定的问题,而不是我用Jest模拟并用jasmine监视的行为。

Do you have an idea what it doesn't work ? 您有什么不知道的主意吗?

EDIT : My test displayed me an error like my spy has never been called 编辑:我的测试向我显示了一个错误,例如从未调用过我的间谍

Your action-handler is actually a action handler factory. 您的动作处理程序实际上是一个动作处理程序工厂。 In actionHandler[FETCH_REMOTE] , you are creating a new function. actionHandler[FETCH_REMOTE] ,您正在创建一个新函数。 The returned function taskes dispatch as a parameter and invokes the code you are showing. 返回的函数将任务dispatch为参数并调用您显示的代码。
This means that your test code will never call any function on the spy, as the created function is never invoked. 这意味着您的测试代码将永远不会调用间谍程序上的任何函数,因为永远不会调用创建的函数。

I think you will need to create a mock dispatch function and do something like this: 我认为您将需要创建一个模拟dispatch功能并执行以下操作:

let dispatchMock = jest.fn(); // create a mock function
actionHandler[FETCH_REMOTE](slug)(dispatchMock);

EDIT: 编辑:

To me, your actionHandler looks more like an actionCreator , as it is usually called in redux terms, though I personally prefer to call them actionFactories because that is what they are: Factories that create actions. 对我来说,您的actionHandler看起来更像是actionCreator ,通常用redux术语来称呼,尽管我个人更喜欢将它们actionFactories因为这就是它们:创建动作的工厂。
As you are using thunks (?) your actionCreater (which is misleadingly named actionHandler ) does not directly create an action but another function which is invoked as soon as the action is dispatched. 当你正在使用thunks (?)你actionCreater (这是误导命名actionHandler )不直接创建一个action ,但它一旦动作被分派调用另一个函数。 For comparison, a regular actionCreator looks like this: 为了进行比较,常规的actionCreator如下所示:

updateFilter: (filter) => ({type: actionNames.UPDATE_FILTER, payload: {filter: filter}}),

A actionHandler on the other hand reacts to actions being dispatched and evaluates their payload. 另一方面, actionHandler对要分派的动作做出反应并评估其有效负载。

Here is what I would do in your case: 在您的情况下,这就是我要做的:

Create a new object called actionFactories like this: 创建一个名为actionFactories的新对象,如下所示:

const actionFactories = {

    fetchRemote(slug): (slug) => {
        return async dispatch => {
            dispatch(loading());
            console.log(fetch()); // Displays the default fetch promise result
            let response = await fetch(Constants.URL + slug);

            var responseAction;
            if (/* determine success of response */) {
                responseAction = actionFactories.fetchSuccessful(response);
            } else {
                responseAction = actionFactories.fetchFailed();
            }

            dispatch(responseAction);
        };
    }

    fetchFailed(): () => ({type: FETCH_FAILED, }),
    fetchSuccessful(response): () => ({type: FETCH_FAILED, payload: response })
};

Create an actionHandler for FETCH_FAILED and FETCH_SUCCESSFUL to update the store based on the response. FETCH_FAILEDFETCH_SUCCESSFUL创建一个actionHandler,以根据响应更新商店。

BTW: Your console.log statement does not make much sense too me, since fetch just returns a promise. 顺便说一句:您的console.log语句对我也没有多大意义,因为fetch只是返回一个承诺。

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

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