Я борюсь с написанием правильного теста для компонента, который защищает некоторые маршруты и программно перенаправляет неавторизованных пользователей. Компонент выглядит следующим образом:
import { useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { isAuthed } from 'redux/selectors/auth';
const mapState = state => ({
isAuthenticated: isAuthed(state),
});
const LoginShield = ({ children }) => {
const { isAuthenticated } = useSelector(mapState);
const history = useHistory();
useEffect(() => {
if (!isAuthenticated) {
history.push('/login');
}
}, [isAuthenticated]);
return children;
};
export default LoginShield;
Я хотел бы проверить, что компонент перенаправляет неаутентифицированного пользователя и не перенаправляет аутентифицированного пользователя (два базовых c теста). Я попробовал несколько подходов, используя Jest / Enzyme или Jest / ReactTestingLibrary, и не могу найти хорошего решения.
Пока мой тест - беспорядок, но я поделюсь им, чтобы кто-то мог показать мне, в чем проблема:
import React, { useEffect } from 'react';
import { act } from 'react-dom/test-utils';
import { mount } from 'enzyme';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import rootReducer from 'redux/reducers';
import LoginShield from 'components/LoginShield/LoginShield';
describe('LoginShield component', () => {
let wrapper;
let historyMock;
beforeEach(() => {
const initialState = { auth: { loginId: 'Foo' } };
const store = createStore(rootReducer, initialState);
historyMock = {
push: jest.fn(),
location: {},
listen: jest.fn(),
};
jest.mock('react-redux', () => ({
useSelector: jest.fn(fn => fn()),
}));
wrapper = mount(
<Provider store={store}>
<Router history={historyMock}>
<LoginShield>
<h5>Hello Component</h5>
</LoginShield>
</Router>
</Provider>,
);
});
it('renders its children', () => {
expect(wrapper.find('h5').text()).toEqual('Hello Component');
});
it('redirects to the login page if user is not authenticated', async () => {
await act(async () => {
await Promise.resolve(wrapper);
await new Promise(resolve => setImmediate(resolve));
wrapper.update();
});
// is the above necessary?
console.log(historyMock.push.mock.calls);
// returns empty array
// ... ?
});
it('doesn`t redirect authenticated users', () => {
// .... ?
});
});
Любые советы приветствуются! Заранее спасибо. :)