How to Test Remix Application: Simple Guide with Examples
To test a
Remix application, use Jest with @testing-library/react for component tests and @remix-run/testing for route loader and action tests. Write tests that simulate user interactions and verify rendered output or data loading behavior.Syntax
Testing a Remix app involves three main parts:
- Render the component: Use
render()from@testing-library/reactto display UI components. - Simulate user events: Use
fireEventoruserEventto mimic clicks, typing, etc. - Test loaders and actions: Use
@remix-run/testinghelpers likecreateRequestandcallLoaderto test data loading and form submissions.
javascript
import { render, screen, fireEvent } from '@testing-library/react'; import { createRequest, callLoader } from '@remix-run/testing'; // Render component render(<MyComponent />); // Simulate click fireEvent.click(screen.getByText('Submit')); // Test loader const request = createRequest('/path'); const response = await callLoader(loaderFunction, { request });
Example
This example shows how to test a Remix route component with a loader and a button click that updates UI.
javascript
import { render, screen, fireEvent } from '@testing-library/react'; import { createRequest, callLoader } from '@remix-run/testing'; import { loader } from '~/routes/example'; import Example from '~/routes/example'; test('loader returns data and button updates UI', async () => { // Test loader function const request = createRequest('/example'); const loaderResponse = await callLoader(loader, { request }); const data = await loaderResponse.json(); expect(data.message).toBe('Hello from loader'); // Render component render(<Example />); // Check initial text from loader expect(screen.getByText(/Hello from loader/i)).toBeInTheDocument(); // Simulate button click fireEvent.click(screen.getByRole('button', { name: /Click me/i })); // Check updated UI expect(screen.getByText(/Button clicked/i)).toBeInTheDocument(); });
Output
PASS loader returns data and button updates UI
Common Pitfalls
- Not mocking Remix loader or action requests properly can cause tests to fail or hang.
- Forgetting to wrap components with Remix
RemixBrowserorRemixServercontext when needed. - Using legacy React testing methods instead of
@testing-library/reactwhich is more user-focused. - Ignoring async behavior in loaders and actions; always use
awaitand async test functions.
javascript
/* Wrong: Not awaiting loader response */ const response = callLoader(loader, { request }); // Missing await /* Right: Await loader response */ const response = await callLoader(loader, { request });
Quick Reference
Summary tips for testing Remix apps:
- Use
@testing-library/reactfor UI rendering and user event simulation. - Use
@remix-run/testingto test loaders and actions with mock requests. - Always write async tests for data loading and form submissions.
- Mock external APIs or database calls inside loaders/actions for isolated tests.
- Run tests with
jestor your preferred test runner.
Key Takeaways
Use @testing-library/react to render Remix components and simulate user actions.
Test Remix loaders and actions with @remix-run/testing helpers and mock requests.
Always write async tests and await loader or action calls to handle data properly.
Wrap components with Remix context if they depend on routing or data loading.
Mock external dependencies in loaders/actions to keep tests fast and reliable.