Skip to content

Strange behavor when using renderHook with wrapper option #1325

Open
@zero88

Description

@zero88
  • @testing-library/react version: 14.3.1 + 15.0.7
  • Testing Framework and version:
{
  "devDependencies": {
    "@testing-library/react": "15.0.7"
    "jest": "29.7.0",
    "jest-environment-jsdom": "29.7.0",
    "react": "18.3.1"
  }
}

Relevant code or config:

{
  "engines": {
    "node": "20",
    "npm": "10",
    "yarn": "PLEASE USE NPM"
  }
}

What you did:

import { renderHook } from '@testing-library/react';
import React, { ReactElement } from 'react';

interface WrapperProps {
  color?: string;
  onInvoke?: jest.Mock;
  children?: any;
}

let mockWrapperFn = jest.fn();

const Wrapper = (props?: WrapperProps): ReactElement => {
  const bgColor = props?.color ?? 'black';
  const onInvoke = props?.onInvoke ?? mockWrapperFn;
  console.log(`GIVEN PROPS color: ${bgColor}`);
  onInvoke(`INSIDE WRAPPER: ${bgColor}`);
  return <div style={{ backgroundColor: bgColor }}>hello</div>;
};

const useHookTest = (onInvoke: jest.Mock) => {
  onInvoke('INSIDE HOOK');
  return 'hello-guy';
};

afterEach(() => jest.clearAllMocks());

test('not call hook with custom wrapper', () => {
  const mockHookFn = jest.fn();
  const { result } = renderHook(() => useHookTest(mockHookFn), {
    wrapper: () => Wrapper({ color: 'red', onInvoke: mockWrapperFn }),
  });

  expect(mockWrapperFn).toHaveBeenCalledTimes(1);
  expect(mockWrapperFn).toHaveBeenLastCalledWith('INSIDE WRAPPER: red');
  expect(mockHookFn).toHaveBeenCalledTimes(1);
  expect(mockHookFn).toHaveBeenLastCalledWith('INSIDE HOOK');
  expect(result.current).toBe('hello-guy');
});

test('not call hook with default wrapper', () => {
  const mockHookFn = jest.fn();
  const { result } = renderHook(() => useHookTest(mockHookFn), { wrapper: Wrapper });

  expect(mockWrapperFn).toHaveBeenCalledTimes(1);
  expect(mockWrapperFn).toHaveBeenLastCalledWith('INSIDE WRAPPER: black');
  expect(mockHookFn).toHaveBeenCalledTimes(1);
  expect(mockHookFn).toHaveBeenLastCalledWith('INSIDE HOOK');
  expect(result.current).toBe('hello-guy');
});

test('call hook without wrapper', () => {
  const mockHookFn = jest.fn();
  const { result } = renderHook(() => useHookTest(mockHookFn));

  expect(mockWrapperFn).toHaveBeenCalledTimes(0);
  expect(mockHookFn).toHaveBeenCalledTimes(1);
  expect(mockHookFn).toHaveBeenLastCalledWith('INSIDE HOOK');
  expect(result.current).toBe('hello-guy');
});

What happened:

renderHook does not render hook with wrapper option

image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions