Testing next/image can feel annoying at first. A lot of test failures happen because Next.js Image has optimization behavior that does not behave like a normal img in Jest.
The easiest fix is to mock it as a plain img and test output you actually care about.
Why tests fail with next/image
next/image does more than render a simple image tag. It transforms props and adds optimization logic. In unit tests, this can cause:
- unexpected
srcvalues - missing required width/height behavior
- rendering differences that are not useful for UI unit tests
For most component tests, you just need to verify image alt text and image source exists.
Simple mock for Jest
Add this mock in your test file (or in your global Jest setup):
jest.mock('next/image', () => ({
__esModule: true,
default: (props: React.ImgHTMLAttributes<HTMLImageElement>) => {
// Keep test behavior predictable by rendering a real img
// @ts-expect-error - Next Image props are wider than native img props
return <img {...props} />;
},
}));
Now your tests can interact with image output in a normal way.
Example component test
import { render, screen } from '@testing-library/react';
import ProductCard from './ProductCard';
test('shows product thumbnail', () => {
render(<ProductCard name="Keyboard" imageUrl="/images/keyboard.png" />);
const image = screen.getByRole('img', { name: /keyboard/i });
expect(image).toBeInTheDocument();
expect(image).toHaveAttribute('src', '/images/keyboard.png');
});
Focus on behavior that users care about, not internal implementation of Next.js optimization.
Put mock in setup file (recommended)
If many tests use next/image, place the mock once in your Jest setup file.
Example jest.setup.ts:
import '@testing-library/jest-dom';
jest.mock('next/image', () => ({
__esModule: true,
default: (props: React.ImgHTMLAttributes<HTMLImageElement>) => {
// @ts-expect-error - okay in tests
return <img {...props} />;
},
}));
Then register setup in Jest config:
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts']
What you should test (and skip)
Good checks:
- image is rendered
- alt text is correct
- fallback image renders when URL is missing
Usually skip in unit tests:
- Next.js image optimization internals
- generated URL params from image loader
- browser-level image loading timing