Я тестирую функциональный компонент, использующий React-Hooks и Redux-Saga. Я могу передать параметры в URL для компонента, потому что они являются компонентом страницы входа.
Мой URL-адрес, который я передаю, является 'localhost / access / параметр ', и когда этот параметр существует, мне нужно вызвать асинхронную редукционную сагу, и, если выборка в порядке, я помещаю результат в избыточный -хранить. Когда результат находится в избыточном хранилище, у меня есть useEffect, которое проверяет результат, и, если все в порядке, я помещаю ее во вход.
Я могу смоделировать результат с помощью axios, но я перехожу на использование только fetch . я издеваюсь, но когда я использую
mount(component)
, предоставленный энзимом, я не знаю, как ждать редукса-саги, чтобы запрос и использование эффекта выполняли вашу работу. Я помещаю консольный журнал в эффект, сагу и записываю реквизиты ввода, чтобы увидеть ваше значение prop , но значение всегда пусто. Я пытался использовать setImmediate()
и process.nextTick()
.
Ссылки, которые я использую для написания кода: 1 , 2 , 3
Я использую formik, поэтому они передают мне некоторые реквизиты.
Мой компонент
const Login = ({
setFieldError, errors, response, fetchDomain, location, values, handleChange, handleBlur, setFieldValue, history,
}) => {
useEffect(() => {
async function fetchUrlDomain() {
const { pathname } = location;
const [, , domain] = pathname.split('/');
if (typeof domain !== 'undefined') {
await fetchDomain(domain);
}
}
fetchUrlDomain();
}, [fetchDomain, location]);
useEffect(() => {
if (typeof response === 'string') {
setFieldError('domain', 'Domain not found');
inputDomain.current.focus();
} else if (Object.keys(response).length > 0) {
setFieldValue('domain', response.Domain);
setFieldError('domain', '');
}
}, [response, setFieldValue, setFieldError]);
return (
<input name="domain" id="domain" value={values.domain} onChange={handleChange} onBlur={handleBlur} type="text" />
);
}
const LoginFormik = withFormik({
mapPropsToValues: () => ({ domain: '' }),
enableReinitialize: false,
validateOnBlur: false,
validateOnChange: false,
})(Login);
const mapStateToProps = () => ({ });
const mapDispatchToProps = dispatch => ({
fetchDomain: (value) => {
dispatch(action({}, constants.RESET_RESPONSE_DOMAIN));
dispatch(action(value, constants.FETCH_DOMAIN_REQUEST));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(LoginFormik);
Моя сага
export function* fetchDomain(action) {
const url = yield `${mainUrl}/${action.payload}`;
try {
const response = yield fetch(url).then(res => res.json());
yield put(reduxAction(response , constants.FETCH_DOMAIN_SUCCESS));
} catch (e) {
yield put(reduxAction(e, constants.FETCH_DOMAIN_FAILURE));
}
}
Мой редуктор
case constants.FETCH_DOMAIN_FAILURE:
return { ...initialState, response: 'Domain not found' };
case constants.FETCH_DOMAIN_SUCCESS: {
const { payload } = action;
return {
...initialState,
id: payload.Id,
apis: payload.Apis,
response: payload,
};
}
case constants.RESET_RESPONSE_DOMAIN:
return { ...initialState };
Мой тест
it('input with fetch only', (done) => {
const mockSuccessResponse = {
Id: 'fafafafa',
Apis: [],
Domain: 'NAME',
};
const mockJsonPromise = Promise.resolve(mockSuccessResponse);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);
const wrapper = mount(
<Provider store={store}>
<LoginForm
history={{ push: jest.fn() }}
location={{ pathname: 'localhost/login/Domain' }}
/>
</Provider>,
);
process.nextTick(() => {
const input = wrapper.find('#domain');
console.log(input.props());
expect(input.props().value.toLowerCase()).toBe('name');
global.fetch.mockClear();
done();
});
});
Я ожидаю, что мой вклад имеет значение, но он нет. Я пытался использовать jest-fetch-mock , но просто не работал, и я хочу использовать нативные методы jest, без тридцати партийных библиотек.