Я пишу тесты для своих асинхронных действий. Я абстрагировал свои вызовы axios в отдельный класс. Если я хочу протестировать свое асинхронное избыточное действие, как мне написать макет для api.js, чтобы sampleAction.test.js прошел? Спасибо!
API.js:
import axios from 'axios';
let apiUrl = '/api/';
if (process.env.NODE_ENV === 'test') {
apiUrl = 'http://localhost:8080/api/';
}
export default class Api {
static async get(url) {
const response = await axios.get(`${apiUrl}${url}`, {withCredentials: true});
return response;
}
}
пример действия.js: импортировать API из './api';
export const fetchData = () => async (dispatch) => {
try {
const response = await Api.get('foo');
dispatch({
type: 'RECEIVE_DATA',
data: response.data.data,
});
} catch (error) {
handleError(error);
}
};
образецAction.test.js:
import store from './store';
test('testing RECEIVE_DATA async action', () => {
const expectedActions = [
{ type: 'RECEIVE_DATA', data: 'payload' },
];
return store.dispatch(actions.fetchData()).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
Спасибо @CharlieStanard, я взглянул на это. Я вижу, что это ссылается на насмешку над экземпляром axios.create(), однако я просто немного сбит с толку, если это то, что я должен использовать для макета, и как это сделать. Я имею в виду, если я назову это издевательством, что произойдет? Разве я не хочу, чтобы он издевался над переданным ему URL-адресом и возвращал определенное значение?
В качестве альтернативы см. github.com/ctimmerm/аксиос-макет-адаптер



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете издеваться над Api.get следующим образом:
import { fetchData } from './sampleAction';
import Api from './api';
let getMock;
beforeEach(() => {
getMock = jest.spyOn(Api, 'get');
getMock.mockResolvedValue({ data: { data: 'mock data' } });
});
afterEach(() => {
getMock.mockRestore();
});
test('testing RECEIVE_DATA async action', async () => {
const dispatch = jest.fn();
await fetchData()(dispatch);
expect(getMock).toHaveBeenCalledWith('foo'); // Success!
expect(dispatch).toHaveBeenCalledWith({
type: 'RECEIVE_DATA',
data: 'mock data'
}); // Success!
});
... или вы можете издеваться над api.js следующим образом:
import { fetchData } from './sampleAction';
import Api from './api';
jest.mock('./api', () => ({
get: jest.fn(() => Promise.resolve({ data: { data: 'mock data' } }))
}));
test('testing RECEIVE_DATA async action', async () => {
const dispatch = jest.fn();
await fetchData()(dispatch);
expect(Api.get).toHaveBeenCalledWith('foo'); // Success!
expect(dispatch).toHaveBeenCalledWith({
type: 'RECEIVE_DATA',
data: 'mock data'
}); // Success!
});
... или вы можете автоматически смоделировать api.js и заполнить возвращаемое значение для Api.get:
import { fetchData } from './sampleAction';
import Api from './api';
jest.mock('./api'); // <= auto-mock
Api.get.mockResolvedValue({ data: { data: 'mock data' } });
test('testing RECEIVE_DATA async action', async () => {
const dispatch = jest.fn();
await fetchData()(dispatch);
expect(Api.get).toHaveBeenCalledWith('foo'); // Success!
expect(dispatch).toHaveBeenCalledWith({
type: 'RECEIVE_DATA',
data: 'mock data'
}); // Success!
});
...или вы можете создать ручной макет по адресу ./__mocks__/api.js:
export default {
get: jest.fn(() => Promise.resolve({ data: { data: 'mock data' } }))
}
... и активируйте его в своем тесте следующим образом:
import { fetchData } from './sampleAction';
import Api from './api';
jest.mock('./api'); // <= activate manual mock
test('testing RECEIVE_DATA async action', async () => {
const dispatch = jest.fn();
await fetchData()(dispatch);
expect(Api.get).toHaveBeenCalledWith('foo'); // Success!
expect(dispatch).toHaveBeenCalledWith({
type: 'RECEIVE_DATA',
data: 'mock data'
}); // Success!
});
Спасибо @brian-lives-outdoors, это фантастика!
Вы смотрели github.com/axios/moxios?