Jest+React Native Testing Library: How to test an image src?

Viewed 35024

In my new React Native app, I want to add some Jest tests.

One component renders a background image, which is located directly in the project in assets folder.

Now I stumbled about how to test if this image is actually taken from this path, therefore present in the component, and rendered correctly.

I tried using toHaveStyle from @testing-library/jest-native with a container, which returned the error toHaveStyleis not a function. Then I tried the same with queryByTestId, same error. When I do expect(getByTestId('background').toBeInTheDocument); then I feel this is useless, because it only checks if an element with this testId is present, but not the image source.

Please, how can I test this? Does it actually make sense to test an image source after all?

Here is my code:

1.) The component that should be tested (Background):

const Background: React.FC<Props> = () => {
  const image = require('../../../../assets/images/image.jpg');
    
  return (
    <View>
      <ImageBackground testID="background" source={image} style={styles.image}></ImageBackground>
    </View>
  );
};

2.) The test:

import React from 'react';
import {render, container} from 'react-native-testing-library';
import {toHaveStyle} from '@testing-library/jest-native';
import '@testing-library/jest-native/extend-expect';
import Background from '../Background';

describe('Background', () => {   
  test('renders Background image', () => {
    const {getByTestId} = render(<Background></Background>);
    expect(getByTestId('background').toBeInTheDocument);

/*    const container = render(<Background background={background}></Background>);
expect(container).toHaveStyle(
  `background-image: url('../../../../assets/images/image.jpg')`,
); */

/*     expect(getByTestId('background')).toHaveStyle(
  `background-image: url('../../../../assets/images/image.jpg')`,
); */

  });
});
4 Answers

If you're using @testing-library/react rather than @testing-library/react-native, and you have an alt attribute on your image, you can avoid using getByDataTestId and instead use getByAltText.

it('uses correct src', async () => {
    const { getByAltText } = await render(<MyComponent />);

    const image = getByAltText('the_alt_text');

    expect(image.src).toContain('the_url');
    // or
    expect(image).toHaveAttribute('src', 'the_url')
});

Documentation.

Unfortunately, it appears that React Native Testing Library does not include getByAltText. (Thank you, @P.Lorand!)

It's a little hard to say because we can't see <ImageBackground> component or what it does... But if it works like an <img> component we can do something like this.

Use a selector on the image component through its role / alt text / data-testid:

const { getByDataTestId } = render(<Background background={background}>
</Background>);

Then look for an attribute on that component:

expect(getByDataTestId('background')).toHaveAttribute('src', '../../../../assets/images/image.jpg')

When I used getByAltText and getByDataTestId I got is not a function error.

So what worked for me was:

const imgSource = require('../../../../assets/images/image.jpg');
const { queryByTestId } = render(<MyComponent testID='icon' source={imgSource}/>);
expect(queryByTestId('icon').props.source).toBe(imgSource);

I use @testing-library/react-native": "^7.1.0

I ran into this issue today and found that if your URI is a URL and not a required file, stitching the source uri onto the testID works nicely.

export const imageID = 'image_id';
...

<Image testID={`${imageID}_${props.uri}`} ... />

Test

import {
  imageID
}, from '.';

...


const testURI = 'https://picsum.photos/200';
const { getByTestId } = render(<Component uri={testURI} />);

expect(getByTestId()).toBeTruthy();

Related