Reputation: 3125
I'm testing a connected functional component in ReactJS using jest and the react-testing-library.
The component renders some input fields and a button. Here's a simplified version of it, in which I decided to leave the full structure of GridContainer
and GridItem
components (from Material-UI) as they might play a role in this issue:
export function Letter(props) {
const [letter, setLetter] = useState({
// not relevant
});
return (
<GridContainer>
<GridItem md={6} sm={6}>
<GridContainer>
<GridItem>
<LetterImageUpload />
</GridItem>
<GridItem>
<LetterText />
</GridItem>
</GridContainer>
</GridItem>
<GridItem md={6} sm={6}>
<LetterAddress />
<GridContainer>
<Button
data-testid="AddToStoreButton"
onClick={() => {
props.addToStore(letter);
}}
>
Add to Store
</Button>
</GridContainer>
</GridItem>
</GridContainer>
);
}
function mapDispatchToProps(dispatch) {
return {
addToStore: letter => {
dispatch({ type: "ADD_TO_STORE", payload: letter });
}
};
}
export default connect(
null,
mapDispatchToProps
)(Letter);
As you can see I export both the dumb component and the connected component (the latter via export default
), so that I can just import { Letter }
in my tests and not bother about the redux store (is this the right way?).
The accompanying test goes like this:
import { Letter } from "components/Letter/Letter.js";
let container = null;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
unmountComponentAtNode(container);
container.remove();
container = null;
});
test("Letter", () => {
act(() => {
render(<Letter addToStore={jest.fn()} />, container);
});
// FIXME: querySelector returns null
container.querySelector('[data-testid="AddToStoreButton"]').simulate("click");
// assert
});
In a debugger I can see that querySelector returns null
regardless of the selector I used.
For instance, I tried the following in the live debugger:
> container.querySelector('[data-testid="AddToCartButton"]')
null
> container.querySelector("button")
null
> container.querySelector("div")
null
I'm clearly doing something spectacularly wrong. Can anyone spot it?
Upvotes: 1
Views: 12909
Reputation: 3125
Following the tip by Anthony, it turned out I was using render
from the react testing library, but actually using as it were the one exported by the "react-dom" library.
The complete solution, using the react testing library looks like this:
import { fireEvent, render } from "@testing-library/react";
test("Letter", () => {
const { getByTestId } = render(<Letter addToStore={() => {}} />);
fireEvent.click(getByTestId("AddToStoreButton"));
// assert
});
Just to add a bit of more context, if you follow the approach shown in the Testing Recipes on ReactJS.org, you'll need to import { render } from "react-dom"
, instead.
Upvotes: 1