DEV Community

Rex
Rex

Posted on

Testing a mui Auto Complete Adaptor Component integrated with React Hook Form

Subject Under Test

A mui auto-complete adaptor component integrated with React Hook Form's form context. It uses the Controller component from React Hook Form(RHF) and configures mui's Autocomplete to handle validations and more. I use this component instead of mui's Autocomplete in all my forms.

Behaviours

  1. It registers the Autocomplete component with RHF's form context
  2. It inherits all the behaviours from mui's' Autocomplete and accepts all Autocomplete props.
  3. It has three modes: edit, locked, and read-only. In edit mode, it renders a functional Autocomplete component. In locked mode and read-only mode, it renders a TextField component.
  4. It supports single and multiple selection modes
  5. It can limit the number of options it renders with optionLimit prop.
  6. It has a build-in required validation rule
  7. It accepts validation rules from rules prop.
  8. It can be locked(non-editable in edit mode), and it would show a lock icon with a tooltip explaining why it is locked.

Variants - a design decision

The component has three variants:

  1. EpicAutocomplete, a regular auto-complete. It has the same API surface as mui's Autocomplete component plus binding props for RHF.
  2. EpicAutocompleteWithManger, an auto-complete with an additional option for managing options, extends EpicAutocomplete and has extra required props: manager and managerLabel.
  3. EpicAutocompleteWithUrl, an auto-complete with a link icon button for users to navigate to the detail page of the selected entity. It extends EpicAutocomplete and has an extra prop: url.

Before writing the tests for this component, I did not have the above variants, and all the functions were crammed into a single component, which was a leaky implementation.

  1. Many instances don't need the manager or URL but carry the baggage with them.
  2. URL require react-router, and it adds unnecessary dependencies to users that don't use it
  3. The component internals are too complicated.

For the new structure, I moved the implementations into a base component called EpicAutocompleteBase.

  1. It is private and not exposed to external libraries. It cannot be used in forms directly.
  2. All three variants are composed of it.

With the above design, the API for the variants are more precise and lean, and they don't carry unnecessary dependencies with them.

I sincerely invite suggestions from my dear readers for a better approach.

Notes

  1. Each variant has its separate tests. Their tests are focused on their public APIs (props)
  2. No direct tests for EpicAutocompleteBase because three variants are testing it.

Code

Discussion (0)