Get 2024 Templates Mega Bundle!14 Bootstrap, Vue & React Templates + 3 Vector Sets
Get for 99$

How to test in react


Hi there,

I would like to test a simple KT Menu component in react. It seems that the button click event does not apply the "show" class to the menu element in the test as expected. Can you please point me in the right direction on how to test KT Menu components?

Thanks!


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

Replies (6)


Hi Tamas,

Could you please specify which Metronic version are you using?

We are initializing all kt-menu items using typescript component src/_metronic/assets/ts/components/MenuComponent.ts, make sure that components initialization function is triggered in src/_metronic/layout/MasterInit.tsx.

Here is component usage example.

<a
href="#"
className={clsx("btn btn-sm btn-flex fw-bold", daterangepickerButtonClass)}
data-kt-menu-trigger="click"
data-kt-menu-placement="bottom-end"
>
<KTSVG
path="/media/icons/duotune/general/gen031.svg"
className="svg-icon-6 svg-icon-muted me-1"
/>
Filter
</a>

<div className="menu menu-sub menu-sub-dropdown w-250px w-md-300px" data-kt-menu="true">
<div className="px-7 py-5">
<div className="fs-5 text-dark fw-bolder">Filter Options</div>
</div>

<div className="separator border-gray-200"></div>

<div className="px-7 py-5">
<div className="mb-10">
<label className="form-label fw-bold">Status:</label>

<div>
<select
className="form-select form-select-solid"
data-kt-select2="true"
data-placeholder="Select option"
data-allow-clear="true"
defaultValue={"1"}
>
<option></option>
<option value="1">Approved</option>
<option value="2">Pending</option>
<option value="3">In Process</option>
<option value="4">Rejected</option>
</select>
</div>
</div>

<div className="mb-10">
<label className="form-label fw-bold">Member Type:</label>

<div className="d-flex">
<label className="form-check form-check-sm form-check-custom form-check-solid me-5">
<input className="form-check-input" type="checkbox" value="1" />
<span className="form-check-label">Author</span>
</label>

<label className="form-check form-check-sm form-check-custom form-check-solid">
<input className="form-check-input" type="checkbox" value="2" defaultChecked={true} />
<span className="form-check-label">Customer</span>
</label>
</div>
</div>

<div className="mb-10">
<label className="form-label fw-bold">Notifications:</label>

<div className="form-check form-switch form-switch-sm form-check-custom form-check-solid">
<input
className="form-check-input"
type="checkbox"
value=""
name="notifications"
defaultChecked={true}
/>
<label className="form-check-label">Enabled</label>
</div>
</div>

<div className="d-flex justify-content-end">
<button
type="reset"
className="btn btn-sm btn-light btn-active-light-primary me-2"
data-kt-menu-dismiss="true"
>
Reset
</button>

<button type="submit" className="btn btn-sm btn-primary" data-kt-menu-dismiss="true">
Apply
</button>
</div>
</div>
</div>



Regards,
Lauris Stepanovs,
Keenthemes Support Team



Hi Lauris,

I am using the default MasterInit.tsx, and it looks good. I have the latest available version:
REACT_APP_VERSION=v8.1.5

Here is a simple test that fails. In chrome dev-tools, I can see the "show" class being added to the test-menu component on button click.


it("should open menu when button is clicked", () => {
render(<TestFilter />)
const button = screen.getByTestId("filter-button")
userEvent.click(button)
expect(screen.getByTestId("test-menu")).toHaveClass("show")
})


How could this be tested?

Thanks,
Tamas



Hi,

We haven't tried testing components in this way but it seems like this test will only trigger component functions and button will not have events that were initialized in a different component. To fix this you can move menu initialization into your TestFilter component.

Just call MenuComponent.bootstrap().

Regards,
Lauris Stepanovs,
Keenthemes Support Team



Hi Lauris!

Thanks for your reply. I tried to do it like this:


function TestFilter() {
useEffect(() => {
MenuComponent.bootstrap()
}, [])

return (
<div>
<a
href="#"
className={clsx("btn btn-sm btn-flex fw-bold")}
data-kt-menu-trigger="click"
data-kt-menu-placement="bottom-end"
data-testid="filter-button"
>
<KTSVG
path="/media/icons/duotune/general/gen031.svg"
className="svg-icon-6 svg-icon-muted me-1"
/>
Filter
</a>
<div
className="menu menu-sub menu-sub-dropdown w-250px w-md-300px"
data-kt-menu="true"
data-testid="test-menu"
>
<div className="px-7 py-5">
<div className="fs-5 text-dark fw-bolder">Filter Options</div>
</div>{" "}
<div className="separator border-gray-200"></div>{" "}
<div className="px-7 py-5">
<div className="mb-10">
<label className="form-label fw-bold">Status:</label>{" "}
<div>
<select
className="form-select form-select-solid"
data-kt-select2="true"
data-placeholder="Select option"
data-allow-clear="true"
defaultValue={"1"}
>
<option></option>
<option value="1">Approved</option>
<option value="2">Pending</option>
<option value="3">In Process</option>
<option value="4">Rejected</option>
</select>
</div>
</div>{" "}
<div className="mb-10">
<label className="form-label fw-bold">Member Type:</label>{" "}
<div className="d-flex">
<label className="form-check form-check-sm form-check-custom form-check-solid me-5">
<input className="form-check-input" type="checkbox" value="1" />
<span className="form-check-label">Author</span>
</label>{" "}
<label className="form-check form-check-sm form-check-custom form-check-solid">
<input
className="form-check-input"
type="checkbox"
value="2"
defaultChecked={true}
/>
<span className="form-check-label">Customer</span>
</label>
</div>
</div>{" "}
<div className="mb-10">
<label className="form-label fw-bold">Notifications:</label>{" "}
<div className="form-check form-switch form-switch-sm form-check-custom form-check-solid">
<input
className="form-check-input"
type="checkbox"
value=""
name="notifications"
defaultChecked={true}
/>
<label className="form-check-label">Enabled</label>
</div>
</div>{" "}
<div className="d-flex justify-content-end">
<button
type="reset"
className="btn btn-sm btn-light btn-active-light-primary me-2"
data-kt-menu-dismiss="true"
>
Reset
</button>
<button type="submit" className="btn btn-sm btn-primary" data-kt-menu-dismiss="true">
Apply
</button>
</div>
</div>
</div>
</div>
)
}

export default TestFilter


Still doesn't work. What could be the issue?

Thanks,
Tamas



Hi Tamas,

Unfortunately, we haven't tried to write React component tests at the moment, so we cannot give you a lot of help with this problem.

If this code works inside your browser then the issue is related to specific of your testing library. You can refer to their documentation and check how components are rendered in this context.

Regards,
Lauris Stepanovs,
Keenthemes Support Team



Hey Tamas,

I totally get the frustration with testing React components, especially when it comes to handling events and class changes. One effective way to test the button click event and class application is by using a testing library like React Testing Library or Enzyme.

Firstly, make sure you're simulating the button click correctly in your test. Then, check if the "show" class is being applied by accessing the component's state or checking the DOM after the click event.

For React Testing Library, you can use 'fireEvent.click()' to simulate the click, and then assert the class using 'getByTestId' or similar methods.

Also, consider using snapshot testing to capture the component's rendered output and ensure it stays consistent.

Remember, keep your tests focused and test one behavior at a time for better clarity and debugging.

If you share a snippet of your test code, I might be able to give more specific advice.


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(
Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(