Typescript,在Redux操作中测试Api调用,在Enzyme,Jest中模拟类

时间:2019-04-09 08:16:29

标签: reactjs typescript unit-testing react-redux jestjs

我有一个问题,我需要模拟在我的redux动作中调用的类Api,该类调用axios get,post等...。我一直在关注this教程,该教程解释了如何模拟axios,以及this教程,该如何模拟一个类,但是两种方法都不起作用。

现在输入一些代码...这是我需要测试的操作类型的示例。

export const getAlldata = (id: string) => {
    return (dispatch: any) => {
        dispatch(beginAjaxRequest(id, types.BEGIN_GET_DATA_AJAX));
        return Api.get("/data/data").then((response: any) => {
            dispatch(getDataSuccess(response.data, id))
        }).catch((error) => {
            dispatch(handleAjaxError(id, new Alert({ id: id, title: "Error getting data", message: error.toString(), timestamp: Date.now(), error: true })));
        });
    }
}

和此调用的Api的一部分。

import axios from 'axios';

class Api {
    static get(path: string) {
        return axios({
            method: 'get',
            url: (global as any).apiDomain + path,
            headers: {
                Authorization: "Bearer " + (global as any).authentication.getToken(),
            "Content-Type": "application/json"
            }
        });
    }
}

export default Api;

我曾尝试在src / mocks / Api中进行模拟(模拟前后有两个下划线)

import * as Promise from 'bluebird';
import { getTestData } from '../models/_tests/TestData';

class Api {
    static get(path: string) {
        switch (path) {
            case "/data/data":
                return Promise.resolve({
                    data: getTestData(3)
                });
            default:
                return {};
        }
    }
}

export default Api;

并在我的setupTests中进行设置。

import * as Enzyme from 'enzyme';
import Api from './__mocks__/Api';
const Adapter = require("enzyme-adapter-react-16");

(global as any).Api = Api;

Enzyme.configure({ adapter: new Adapter() });

并在我的实际测试中打电话给我...

describe('thunk actions', () => {

    var middleware = [thunk];
    var mockStore = configureMockStore(middleware);
    afterAll(() => {
        cleanAll();
    });

    test('getAllData gets all data', (done: any) => {
        var store = mockStore({});
        jest.mock('../../api/Api'); // path to real Api
        var id = generateGuid();
        store.dispatch<any>((getAllData(id))).then(() => {
            done();
        });
    });
});

所以很明显,这实际上并没有测试任何东西,我只是想让它正常工作,但是我一直在真实的Api而不是模拟中得到错误。我也尝试过模拟axios,但是我遇到了同样的错误(无法获取未定义的令牌),所以这似乎并没有取代axios或Api,有人可以看到我要去哪里了吗?

1 个答案:

答案 0 :(得分:1)

您知道将问题发布到stackoverflow并在一周多的时间内获得0个答案和0个响应时感到很困惑...不太理想,但我发现了一种解决方法,可以在我的重击操作中覆盖Api类将Api类导入到我所有的动作文件中并直接调用它的过程,现在我仅将其导入到我的项目的根目录(App.tsx)中,并使其如下所示进行全局设置(缩小到最低限度)。

import * as React from 'react';
import Api from './api/Api';

export interface State {

}

export interface Props {

}

export class App extends React.Component<Props, State> {

    state = {

    };

    componentWillMount = () => {
        (global as any).Api = Api;
    };





    public render() {
        return (
            <div>

            </div>
        );
    }
}


export default App;

...然后按如下所示对我的重击操作调用Api

export const getAlldata = (id: string) => {
    return (dispatch: any) => {
        dispatch(beginAjaxRequest(id, types.BEGIN_GET_DATA_AJAX));
        return (global as any).Api.get("/data/data").then((response: any) => {
            dispatch(getDataSuccess(response.data, id))
        }).catch((error) => {
            dispatch(handleAjaxError(id, new Alert({ id: id, title: "Error getting data", message: error.toString(), timestamp: Date.now(), error: true })));
        });
    }
}

然后简单地覆盖它是setupTests.ts

import * as Enzyme from 'enzyme';
import Api from './__mocks__/Api';
const Adapter = require("enzyme-adapter-react-16");

(global as any).Api = Api;

Enzyme.configure({ adapter: new Adapter() });

...然后不需要开玩笑的模拟,只需在测试和测试中调用操作即可。

通过用window替换global,该方法也可以在Node之外工作。这样做是可行的,但并不理想,因为我不希望使用全局名称空间,因此,如果有人知道更好的发布方式。