Skip to content

Warning: An update to Animated(View) inside a test was not wrapped in act(...). #1772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
abrahamgalue opened this issue May 25, 2025 · 0 comments
Labels
question Further information is requested

Comments

@abrahamgalue
Copy link

Hey guys, I'm unit testing my React Native components, and one in particular is causing a console.error with a Warning every time I run the tests. I've searched online and through the official documentation for solutions, but I haven't found one. Hopefully, you can help me here, as this is my first time using this tool, which I'm really enjoying.

The error in particular shows this log:

Warning: An update to Animated(View) inside a test was not wrapped in act(...).

When testing, code that causes React state updates should be wrapped in act(...):

act(() => {
/* fire events that update state */
});
/* assert on the output */

This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act 
at C:\mobile\react-native\project\node_modules\react-native\Libraries\Animated\createAnimatedComponent.js:38:59 
at TouchableOpacity (C:\mobile\react-native\project\node_modules\react-native\Libraries\Components\Touchable\TouchableOpacity.js:132:23) 
at TouchableOpacity 
at View 
at View (C:\mobile\react-native\project\node_modules\react-native\jest\mockComponent.js:33:18) 
at showNotifications (C:\mobile\react-native\project\components\ui\Notifications.jsx:11:2)

The tests file that is Notifications-test.jsx looks like this:

import {
	render,
	fireEvent,
	screen,
	waitFor
} from '@testing-library/react-native'
import Notifications from '@/components/ui/Notifications'
import { initialNotifications } from '@/lib/utils'

jest.mock('@/lib/useColorScheme', () => ({
	useColorScheme: () => ({ isDarkColorScheme: true })
}))

jest.mock('@/lib/utils', () => ({
	initialNotifications: jest.fn()
}))

const mockInitialNotifications = initialNotifications

jest.mock('@/components/ui/IconSymbol', () => ({
	IconSymbol: jest.fn(() => <></>)
}))

jest.mock('@/components/ui/Icons', () => ({
	WaterObstructionIcon: jest.fn(() => <></>),
	TemperatureSubstrateIcon: jest.fn(() => <></>)
}))

const mockHandleNotificationPress = jest.fn()
const mockHandleClearNotifications = jest.fn()

const initialNotificationsValue = [
	{
		type: 'waterObstruction',
		content: '60% de agua restante'
	},
	{
		type: 'temperatureSubstrate',
		content: '0.5% obstrucción'
	}
]

describe('<Notifications />', () => {
	beforeEach(() => {
		jest.clearAllMocks()
	})

	test('should render notification button', () => {
		mockInitialNotifications.mockReturnValue(initialNotificationsValue)

		render(
			<Notifications
				showNotifications={false}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		expect(screen.getByRole('button')).toBeOnTheScreen()
	})

	test('should show notification count badge when there are notifications', () => {
		mockInitialNotifications.mockReturnValue(initialNotificationsValue)

		render(
			<Notifications
				showNotifications={false}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		expect(
			screen.getByText(initialNotificationsValue.length.toString())
		).toBeOnTheScreen()
	})

	test('does not show notification count when there are no notifications', () => {
		mockInitialNotifications.mockReturnValue([])

		render(
			<Notifications
				showNotifications={false}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		expect(
			screen.queryByText(initialNotificationsValue.length.toString())
		).not.toBeOnTheScreen()
	})

	test.each(initialNotificationsValue)(
		'should display $count when showNotifications is true',
		({ content }) => {
			mockInitialNotifications.mockReturnValue(initialNotificationsValue)

			render(
				<Notifications
					showNotifications={true}
					handleNotificationPress={mockHandleNotificationPress}
					handleClearNotifications={mockHandleClearNotifications}
				/>
			)

			expect(screen.getByRole('text', { name: content })).toBeOnTheScreen()
		}
	)

	test('should call handleNotificationPress when button is pressed', async () => {
		mockInitialNotifications.mockReturnValue(initialNotificationsValue)

		render(
			<Notifications
				showNotifications={false}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		fireEvent.press(screen.getByRole('button'))
		await waitFor(() => {
			expect(mockHandleNotificationPress).toHaveBeenCalled()
		})
	})

	test('does not call handleNotificationPress when button is disabled', async () => {
		mockInitialNotifications.mockReturnValue([])

		render(
			<Notifications
				showNotifications={false}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		fireEvent.press(screen.getByRole('button'))
		await waitFor(() => {
			expect(mockHandleNotificationPress).not.toHaveBeenCalled()
		})
	})

	test('should render clear notifications button', () => {
		mockInitialNotifications.mockReturnValue(initialNotificationsValue)

		render(
			<Notifications
				showNotifications={true}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		const clearBtn = screen.getByText('Limpiar todo')

		expect(clearBtn).toBeOnTheScreen()
		expect(clearBtn).toHaveStyle({ color: 'white' })
		expect(clearBtn.props).toHaveProperty('className', 'font-bold')
	})

	test('should call handleClearNotifications when clear button is pressed', async () => {
		mockInitialNotifications.mockReturnValue(initialNotificationsValue)

		render(
			<Notifications
				showNotifications={true}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		const clearBtn = screen.getByText('Limpiar todo')

		expect(clearBtn).toBeOnTheScreen()
		expect(clearBtn).toHaveStyle({ color: 'white' })
		expect(clearBtn.props).toHaveProperty('className', 'font-bold')

		fireEvent.press(clearBtn)
		await waitFor(() => {
			expect(mockHandleClearNotifications).toHaveBeenCalled()
		})
	})

	test('should display "+9" when there are 10 or more notifications', () => {
		mockInitialNotifications.mockReturnValue(
			Array(10).fill({
				type: 'waterObstruction',
				content: '60% de agua restante'
			})
		)

		render(
			<Notifications
				showNotifications={false}
				handleNotificationPress={mockHandleNotificationPress}
				handleClearNotifications={mockHandleClearNotifications}
			/>
		)

		expect(screen.getByText('+9')).toBeOnTheScreen()
	})
})

It is important to clarify that all tests are passing correctly, but this warning is displayed, which I find annoying and makes me doubt if I am doing something wrong. I currently use Jest with Expo and I configured it according to its official documentation. If you need any other resources such as the Notifications component code, please let me know. I would really appreciate your help 🙌

@abrahamgalue abrahamgalue added the question Further information is requested label May 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant