npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dbarrett24/testing-utils

v1.0.0

Published

Testing utilities and helpers for React applications

Readme

@yourname/testing-utils

Testing utilities and helpers for React applications with Jotai, React Query, and React Hook Form.

Installation

pnpm add -D @yourname/testing-utils @testing-library/react @testing-library/jest-dom @testing-library/user-event jest

Features

  • Custom render with React Query and Jotai providers
  • Direct Jotai store access for setting/getting atoms in tests
  • React Query mocks for query and mutation states
  • FormWrapper for testing components that use React Hook Form
  • Re-exports all React Testing Library utilities

Usage

Basic Rendering

import { render, screen } from '@yourname/testing-utils';

it('renders component', () => {
    render(<MyComponent />);
    expect(screen.getByText('Hello World')).toBeVisible();
});

With User Interactions

import { render, screen, userEvent } from '@yourname/testing-utils';

it('handles click', async () => {
    render(<Button />);
    
    await userEvent.click(screen.getByText('Click me'));
    
    expect(screen.getByText('Clicked!')).toBeVisible();
});

Testing with Jotai Atoms

import { render, screen, jotaiStore } from '@yourname/testing-utils';
import { userAtom } from '@/atoms/user';

it('uses jotai atom value', () => {
    // Set atom value directly in test
    jotaiStore.set(userAtom, { id: '1', name: 'John' });
    
    render(<UserProfile />);
    
    expect(screen.getByText('John')).toBeVisible();
});

it('reads atom value in test', () => {
    render(<UserForm />);
    
    // Interact with component
    userEvent.type(screen.getByLabelText('Name'), 'Jane');
    userEvent.click(screen.getByText('Save'));
    
    // Read atom value directly
    const user = jotaiStore.get(userAtom);
    expect(user.name).toBe('Jane');
});

Testing with React Query

import { render, screen, querySuccessMock, queryLoadingMock, queryErrorMock } from '@yourname/testing-utils';
import * as hooks from '@/data/useGetUser';

const useGetUserSpy = jest.spyOn(hooks, 'useGetUser');

it('renders loading state', () => {
    useGetUserSpy.mockReturnValue(queryLoadingMock);
    
    render(<UserProfile userId="1" />);
    
    expect(screen.getByText('Loading...')).toBeVisible();
});

it('renders success state', () => {
    useGetUserSpy.mockReturnValue({
        ...querySuccessMock,
        data: { id: '1', name: 'John' }
    });
    
    render(<UserProfile userId="1" />);
    
    expect(screen.getByText('John')).toBeVisible();
});

it('renders error state', () => {
    useGetUserSpy.mockReturnValue(queryErrorMock);
    
    render(<UserProfile userId="1" />);
    
    expect(screen.getByText('Error loading user')).toBeVisible();
});

Testing Forms with React Hook Form

import { render, screen, FormWrapper, userEvent } from '@yourname/testing-utils';

// Component using useFormContext
const EmailField = () => {
    const { register } = useFormContext();
    return <input {...register('email')} />;
};

it('renders form field with default value', () => {
    render(
        <FormWrapper defaultValues={{ email: '[email protected]' }}>
            <EmailField />
        </FormWrapper>
    );
    
    expect(screen.getByDisplayValue('[email protected]')).toBeVisible();
});

it('handles form input', async () => {
    render(
        <FormWrapper defaultValues={{ email: '' }}>
            <EmailField />
        </FormWrapper>
    );
    
    await userEvent.type(screen.getByRole('textbox'), '[email protected]');
    
    expect(screen.getByDisplayValue('[email protected]')).toBeVisible();
});

Custom QueryClient

import { render, screen } from '@yourname/testing-utils';
import { QueryClient } from '@tanstack/react-query';

it('uses custom query client', () => {
    const queryClient = new QueryClient({
        defaultOptions: {
            queries: { staleTime: 10000 }
        }
    });
    
    const { queryClient: returnedClient } = render(<MyComponent />, {
        initialState: { queryClient }
    });
    
    expect(returnedClient).toBe(queryClient);
});

API Reference

render(ui, options)

Custom render function that wraps components with React Query and Jotai providers.

Parameters:

  • ui - React element to render
  • options.initialState - Optional initial state configuration
    • queryClient - Custom QueryClient instance

Returns:

  • All React Testing Library render results
  • queryClient - The QueryClient instance used

jotaiStore

Jotai store instance for direct atom access in tests.

Methods:

  • get(atom) - Get current atom value
  • set(atom, value) - Set atom value

React Query Mocks

Pre-configured mock objects for React Query hooks:

  • querySuccessMock - Success state for useQuery
  • queryLoadingMock - Loading state for useQuery
  • queryErrorMock - Error state for useQuery
  • mutationSuccessMock - Success state for useMutation
  • mutationLoadingMock - Loading state for useMutation
  • mutationErrorMock - Error state for useMutation

FormWrapper

Wrapper component that provides React Hook Form context for testing.

Props:

  • children - Components to render
  • defaultValues - Default form values
  • formOptions - Additional useForm options

Best Practices

1. Use Direct Queries

// ✅ Good - direct query
expect(screen.getByText('Submit')).toBeVisible();

// ❌ Avoid - unnecessary variable
const button = screen.getByText('Submit');
expect(button).toBeVisible();

2. Prefer toBeVisible()

// ✅ Good - tests actual visibility
expect(screen.getByText('Hello')).toBeVisible();

// ❌ Avoid - only tests DOM presence
expect(screen.getByText('Hello')).toBeInTheDocument();

3. Mock at the Hook Level

// ✅ Good - spy on the hook
const useGetUserSpy = jest.spyOn(hooks, 'useGetUser');
useGetUserSpy.mockReturnValue({ ...querySuccessMock, data: mockUser });

// ❌ Avoid - mocking fetch directly
global.fetch = jest.fn();

4. Use userEvent for Interactions

// ✅ Good - simulates real user interactions
await userEvent.click(screen.getByText('Submit'));
await userEvent.type(screen.getByRole('textbox'), 'Hello');

// ❌ Avoid - fireEvent doesn't simulate real events
fireEvent.click(screen.getByText('Submit'));

License

MIT