Background
In the react channel on Spectrum, someone asked how to test that a component displayed data provided by location.state from react-router-dom. I had never done this before, so I sought to find out how to do it.
After some investigation, and trial and error, I came up with the following...
import * as React from "react";
import { render } from "@testing-library/react";
import { Router } from "react-router-dom";
import { createMemoryHistory } from "history";
import { App } from "./App";
it("renders location state", () => {
  const history = createMemoryHistory();
  const state = { a: 123, b: 456 }
  history.push("/", state);
  const { getByText } = render(
    <Router history={history}>
      <App />
    </Router>
  );
  getByText(state.a);
  getByText(state.b);
});
Other Interesting Tidbits
- <MemoryRouter history={createMemoryHistory(...)}>doesn't work
- <BrowserRouter history={createBrowserHistory(...)}>does work, but doesn't typecheck
- According to the docs 
Note: Location state is only supported in createBrowserHistory and createMemoryHistory.
location.state - Some extra state for this location that does not reside in the URL (supported in createBrowserHistory and createMemoryHistory)
Conclusion
So, this seems to work. It passes the tests.
Know of a better way? See any problems? Let me know, thanks.
 

 
    
Top comments (3)
That sort of worked for me, but I still had code in my component that was throwing an error "cannot access property .state of null value", in this case the null value was
location.I did come up with a solution, which is to first grab the history of the component I'm rendering to test and then
rerenderthat component with alocationprop equal tohistory.location. Looking like:That way, my code in the
<Component/>that callsthis.props.location.statedoesn't fail.Sidenote:
renderWithRouteris a utility function I built that uses similar logic to what you have above and returnshistoryalong with...render(<Component />That worked perfectly for me! Thanks for the writeup!
Thanks for the post!
A heads up: eslint will throw
Don't do it - stackoverflow.com/a/66787971/863110.
How to solve this beside make eslint ignoring the line? I have no idea 😕