I am on a journey to acquire the necessary skills for testing software. I will document the techniques and tricks I learned via blog posts.
My first post on testing explains what is a unit test and what makes a test good, the knowledge I gained from reading UNIT TESTING: PRINCIPLES, PRACTICES, AND PATTERNS by Vladimir Khorikov.
Subject Under Test(sut):
a generic cell renderer component for Ag-Grid React renders any given component of type FC<ICellRendererParams>
.
Behaviour
The component being rendered is a small button that uses formatted cell value or cell value as its text. When the user clicks the button, it calls the specified action.
Code
Notes
the test shows how to use the cell renderer in a
TestComponent
, which is sweet, one of the benefits of testingthe test must use the async query
findByText
instead ofgetByText
.findByText
will continuously try to search for the DOM until it finds the element or timeout.getByText
doesn’t work (button not found error) here because the way Ag-Grid renders its cell renderers.use
userEvent
to mimic the user’s click action, which emits a host of events, same as it happens when a user clicks the button in the browser.the
action
is a spy to get asserted because this is the expected behaviour of the sut. I did not directly assert the other expected behaviour, rendering the button with value as its text. But it is tested because the button is used to trigger the event in the test.no mocks. The test is rendering the
AgGridReact
component and theButton
component from@mui/material
Side Notes
The beauty about React is that it embraces functional programming. Its building block is function and encourages the use of pure function. So we can compose simple and pure functions together to make powerful yet simple, elegant and easy to test components.
In this instance, I used a generic cell renderer component to bridge between Ag-Grid’s API and my button component. The useSmallButton hook takes an function and returns a component that uses input. With this generic cell renderer component, I can render anything in a cell. I think Ag-Grid could implement such a generic component to make its API easier to use if not already.
My favourite feature of JavaScript is the spread/rest operator. With this operator, the props of a functional React component is like a contract, an interface, really elegant and powerful.
Top comments (6)
Thanks for sharing Rex, always good to see more examples.
I wrote a post for the AG Grid blog with some React Testing Library tests on an AG Grid implementation blog.ag-grid.com/using-react-testi... if that helps.
You are Ag-Grid! It is such pleasure meeting you. Ag-Grid is my favourite grid library and I use it in all my apps. Thank you very much for providing such a good library.
By any chance is this new generic cell renderer already implemented in Ag-Grid?
Yes! You can pass components directly to cellRenderer now. See ag-grid.com/react-data-grid/compon...
Thanks Rex, I'll forward your compliment on to the dev team :)
I don't think we have a generic cell renderer like that where the control to render is passed in through params.
Thank you Alan. I have updated this blog post for a better implementation. It is the test got me thinking more clearly.
I will definitely have a look at your blogs, thank you for sharing
Hi for some reason I am not seeing the code section.
I was trying to test the renderer on its own but I'm facing an issue when trying to mock the eGridCell for that component. I get the following error on the eGridCell when passing in an HTMLElement object into eGridCell
TypeError: Invalid constructor, the constructor is not part of the custom element registry
I'm using AgGrid v27.3.0 and using jest and the react testing library.