У меня есть проблема, когда мне нужно издеваться над классом Api
, который вызывается в моих действиях с редукцией, этот класс вызывает axios get, post и т. д., которые нужно издеваться. Я следил за учебником это, объясняющим, как издеваться над аксиомами, и учебником это о том, как издеваться над классом, но ни один из подходов не работает.
Теперь немного кода... вот пример действия, которое мне нужно протестировать.
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, но получаю ту же ошибку (не могу получитьToken of undefined), так что это, похоже, не заменяет ни axios, ни Api, может ли кто-нибудь увидеть, где я ошибаюсь?
Вы знаете, что облажались, когда публикуете вопрос в stackoverflow и получаете 0 ответов и 0 ответов в течение недели... Не идеально, но я нашел обходной путь, чтобы переопределить класс Api в моих действиях thunk вместо импорта 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 на мои действия thunk, как показано ниже
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() });
... и тогда нет необходимости в шутливых издевательствах, просто вызывайте действия в своих тестах и тестируйте.
Этот метод также будет работать вне Node, заменив global на window. Это работает, но не идеально, так как я предпочитаю не использовать глобальное пространство имен, поэтому, если кто-нибудь знает лучший способ, отправьте сообщение.