I'm using jest and react-testing-library
to provide unit test coverage for my app.
I use this handy helper function Kent C. Dodds showed in one of his videos:
const renderWithRedux = ui => ({
...render(<Provider store={store}>{ui}</Provider>),
store,
});
I use when I am testing connected components.
I am running into an issue where in order to render a component I needed some data fetched to accuaratly resolve a test, or atleast inject mock data into the store. I am failing to do so
this is my test:
test('navbar accepts props', async () => {
/**
* Something I was testing
*/
const functionToTest = () => async dispatch => {
dispatch(fetchTickets());
};
functionToTest();
const isReady = true;
const mockData = {
sessionInformation: {
ticket: { label: 'Total Tickets' },
sessionDuration: { sessionLabel: 'Session Duration', duration: 42 },
equipment: { type: 'Desktop', operatingSystem: 'Windows' },
},
component: { isReady },
tickets: {
ticketPayload: [
{
number: '1020312039',
shortDescription: 'Accessories',
status: 'Active',
createdOnEpoch: 1512322200000,
},
],
},
};
const data = renderWithRedux(<Navbar props={mockData} />);
});
The component I am testing:
const NavBar = ({
openTickets: { label },
sessionDuration: { sessionLabel, duration },
tickets: { ticketPayload = [] },
isReady,
}) => (!isReady ? (
<Container>
<LogoContainer>
<Logo src={logo} alt="logo" />
<Header>Service Desk</Header>
</LogoContainer>
<SessionInformation className="session">
<NavbarInfo className="session-info">
<p>
<FontAwesomeIcon icon="ticket-alt" className="ticketIcon" />
{label}
</p>
<p>{`${ticketPayload.length} tickets`}</p>
</NavbarInfo>
<NavbarInfo last className="session-info">
<p>
<FontAwesomeIcon icon="clock" className="ticketIcon" />
{sessionLabel}
</p>
<p>{`${duration} minutes`}</p>
</NavbarInfo>
{hasTokens() && (
<Button type="submit" onClick={() => console.log('notes')}>
Notepad
</Button>
)}
</SessionInformation>
</Container>
) : (
<LoaderContainer>
<RingLoader size={100} />
</LoaderContainer>
));
I need to make length calculations with ticketPayload
however the main store is taking priority. Since that information has not been fetched, ticketPayload
's is 0. I want to be able to atleast mock the data to be passed but haven't had any luck using props, as the store takes precedence.
Hope anyone can beam a light of help or share some guidance. Thanks in Advance!
To mock a React component, the most straightforward approach is to use the jest. mock function. You mock the file that exports the component and replace it with a custom implementation. Since a component is basically a function, the mock should also return a function.
test. js extension as when the tests are run using the npm test command, React automatically checks for all the file names with a . test extension and runs the tests.
The official Writing Tests doc from Redux
recommends this approach:
But sometimes you want to test just the rendering of the component, without a Redux store.
In order to be able to test the...component itself without having to deal with the decorator, we recommend you to also export the undecorated component
In other words...export NavBar
as a named export so you can access it in your tests.
Then you can test it directly as a simple UI component that just renders based on the props
you give it.
I created a helper function to wrap my components with redux.
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import initialState from '../store/initialState';
const mockStore = (state = initialState) => configureMockStore()(state);
export const testableComponent = (component, state) =>
(<Provider store={mockStore(state)}>{component}</Provider>);
And then you can call it just like this, passing your state
testableComponent(<YourComponent />, {yourUpdatedMockedState})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With