{"id":13574,"library":"morfi-test-utils","title":"Morfi Test Utilities","description":"morfi-test-utils is a testing utility library specifically designed for forms built with the `morfi` React form library. It provides helpers to simplify the testing of both `morfi` forms and individual `morfi`-connected fields within React components. The library is currently at version 3.0.3 and appears to be actively maintained, with the last major release (v2.0.0) in July 2022. It integrates with `@testing-library/react` and `jest` to offer utilities like mocking form fields, interacting with form values and errors, and asserting field properties and form submissions in an `act`-wrapped manner. Its key differentiator is its tight coupling with `morfi`'s internal structure, providing a more streamlined testing experience compared to generic form testing approaches.","status":"active","version":"3.0.3","language":"javascript","source_language":"en","source_url":"https://github.com/fdc-viktor-luft/morfi","tags":["javascript","typescript"],"install":[{"cmd":"npm install morfi-test-utils","lang":"bash","label":"npm"},{"cmd":"yarn add morfi-test-utils","lang":"bash","label":"yarn"},{"cmd":"pnpm add morfi-test-utils","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for rendering and interacting with React components in tests.","package":"@testing-library/react","optional":false},{"reason":"The core form library this utility is designed to test.","package":"morfi","optional":false},{"reason":"Core React library required by morfi and @testing-library/react.","package":"react","optional":false}],"imports":[{"note":"This library is primarily ESM-first, common with modern React testing setups. Use named imports.","wrong":"const MorfiTestUtils = require('morfi-test-utils');","symbol":"MorfiTestUtils","correct":"import { MorfiTestUtils } from 'morfi-test-utils';"},{"note":"Access `Field` via the default export `MorfiTestUtil` (singular), not the named `MorfiTestUtils` (plural) from the main import. This is often used within `jest.mock`.","wrong":"MorfiTestUtils.Field","symbol":"MorfiTestUtil.Field","correct":"MorfiTestUtil.Field"},{"note":"Access `Form` via the default export `MorfiTestUtil` (singular), not the named `MorfiTestUtils` (plural). Used to wrap custom field components for testing.","wrong":"MorfiTestUtils.Form","symbol":"MorfiTestUtil.Form","correct":"MorfiTestUtil.Form"}],"quickstart":{"code":"import { render } from '@testing-library/react';\nimport { MorfiTestUtils } from 'morfi-test-utils';\nimport React from 'react';\n\n// Mock your morfi-connected input component\n// In a real scenario, this would be a path to your actual Input component\njest.mock('./Input', () => ({\n    Input: (arg) => MorfiTestUtil.Field(arg),\n}));\n\n// A minimal mock form component for demonstration\nconst MyForm = () => (\n    <form>\n        <Input name=\"userName\" label=\"Unique Username\" required={false} />\n    </form>\n);\n\ndescribe('MorfiTestUtils basic form interaction', () => {\n    it('interacts with my form fields and submits', async () => {\n        // mount the form\n        render(<MyForm />);\n        \n        // update some values (already wrapped into \"act\")\n        MorfiTestUtils.fields.userName.change('M4gic');\n        \n        // check for value and properties\n        expect(MorfiTestUtils.fields.userName.value).toBe('M4gic');\n        expect(MorfiTestUtils.fields.userName.dirty).toBe(true);\n        expect(MorfiTestUtils.fields.userName.required).toBe(false);\n        expect(MorfiTestUtils.fields.userName.props.label).toBe('Unique Username');\n\n        // In a real test, you'd trigger validation or submission and assert errors\n        // For simplicity, we'll just submit here.\n        await MorfiTestUtils.submit();\n        \n        // Add assertions for what happens after submit, e.g., an onSubmit mock being called.\n        // expect(someSubmitMock).toHaveBeenCalledWith({ userName: 'M4gic' });\n    });\n});","lang":"typescript","description":"Demonstrates how to mock a Morfi-connected input component, render a form, interact with a field using `MorfiTestUtils`, and assert its properties and values before submission."},"warnings":[{"fix":"Ensure all error message values passed to `ErrorMessage` components or fields are valid React nodes (e.g., strings, numbers, JSX).","message":"The `ErrorMessage` type became more restrictive in v1.1.0, requiring values to be of type `React$Node`. This could break existing code that used simpler string or other non-React node types for error messages.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Upgrade `react` to version `16.2` or higher. Refactor tests to utilize the new automatic value/error provision via the `morfi` context rather than passing them manually to `MorfiTestUtils` methods.","message":"Version 1.0.0 introduced significant breaking changes by switching to the new React Context API, requiring `react@16.2` as a peer dependency. It also changed how values and errors are supplied, no longer needing manual provision.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Ensure your `jest.mock` implementation correctly wraps your component's props with `MorfiTestUtil.Field(arg)` and handles named/default exports as per your component's definition. Example for default export: `{ __esModule: true, default: (arg: any) => MorfiTestUtil.Field(arg) }`.","message":"When mocking components, `MorfiTestUtil.Field` should be called with the arguments your component receives. It's crucial to correctly export your mocked component (named export vs. default export) to match how `jest.mock` is configured.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If using `@testing-library/react`'s `fireEvent` directly, explicitly wrap the interaction and subsequent assertions within `act(() => { ... })` or use `userEvent` methods which are typically `act`-wrapped by default.","message":"All interactions with form fields (e.g., `change`, `blur`, `submit`) using `MorfiTestUtils` are automatically wrapped in `act()`. However, if you perform direct DOM events (e.g., `fireEvent.input`) outside of `MorfiTestUtils` helpers, ensure they are also wrapped in `act()` for correct React state updates in tests.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'/react':71 '2022':64 '3.0.3':49 'act':96 'activ':54 'appear':51 'approach':122 'assert':88 'built':17 'compar':117 'compon':42 'connect':38 'coupl':105 'current':46 'design':14 'differenti':101 'error':86 'experi':116 'field':39,80,89 'form':16,22,34,79,83,92,120 'generic':119 'helper':26 'individu':36 'integr':66 'interact':81 'intern':109 'javascript':123 'jest':73 'juli':63 'key':100 'last':58 'librari':12,23,44,70 'like':77 'maintain':55 'major':59 'manner':98 'mock':78 'morfi':1,5,20,33,37,107 'morfi-test-util':4 'offer':75 'properti':90 'provid':25,111 'react':21,41 'releas':60 'simplifi':28 'specif':13 'streamlin':114 'structur':110 'submiss':93 'test':2,6,10,30,69,115,121 'testing-librari':68 'tight':104 'typescript':124 'util':3,7,11,76 'v2.0.0':61 'valu':84 'version':48 'within':40 'wrap':97","created_at":"2026-04-20T01:55:12.724871+00:00","updated_at":"2026-04-20T01:55:12.724871+00:00","problems":[{"fix":"Change `MorfiTestUtils.Field` to `MorfiTestUtil.Field` when mocking or wrapping fields. Ensure `import { MorfiTestUtils } from 'morfi-test-utils';` is used for the plural named export, and if you need the default export, you might explicitly import it as `import MorfiTestUtil, { MorfiTestUtils } from 'morfi-test-utils';`.","cause":"Attempting to access `Field` via the named export `MorfiTestUtils` instead of the default export `MorfiTestUtil`.","error":"TypeError: (0, _morfiTestUtils.MorfiTestUtils).Field is not a function"},{"fix":"Wrap the `fireEvent` call and subsequent assertions within `act(() => { /* fireEvent call */ });` or `await act(async () => { /* fireEvent call */ });` for async operations.","cause":"A direct DOM interaction (e.g., `fireEvent`) was performed on a component without being wrapped in `act()`, leading to asynchronous state updates not being flushed before assertions.","error":"Invariant Violation: A React `render` is necessary for `act` to be applied correctly. Either wrap your call in `act(() => { ... })` or use `render`."},{"fix":"Install `morfi` as a dependency in your project: `npm install morfi` or `pnpm add morfi` or `yarn add morfi`.","cause":"`morfi` is a peer dependency of `morfi-test-utils` and is not installed in the project.","error":"Error: Cannot find module 'morfi' from 'morfi-test-utils/dist/index.js'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":"https://fdc-viktor-luft.github.io/morfi/","github":"https://github.com/fdc-viktor-luft/morfi","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/morfi-test-utils","openapi_spec":null,"status_page":null,"smithery":null,"categories":["testing"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}