0

I have a component called SearchBox which is used inside SearchSection which is in turn used in MyComponent. SearchBox has a method that uses setTimeout().

SearchBox.tsx

import React from 'react';
export class SearchBox extends React.Component {
  
  private timer: (ReturnType<typeof setTimeout> | null) = null;

  public asyncmethod() {
    if (this.timer !== null) {
      clearTimeout(this.timer);
    }
    this.timer = setTimeout(() => {
      doSomething();
    }, 1000);
    console.log('using original class method');
  }

  render() {
    return (
      <div>
        ...
        ...
        {this.asyncmethod()}
        ...
        ...
      </div>
    );
  }
}

SearchSection.tsx

import React from 'react';
import { SearchBox } from './SearchBox';

export class SearchSection extends React.Component {
  render() {
    return <SearchBox />;
  }
}

MyComponent.tsx

import React from 'react';
import { SearchSection } from './SearchSection';

export class MyComponent extends React.component {
  render() {
    return <SearchSection />;
  }
}

Now I want to test MyComponent using react-testing-library and I want to mock SearchBox with overridden class method that does not use setTimeout. I tried the following

testUtil.tsx

import { SearchBox } from './SearchBox';

class MockedSearchBox extends SearchBox {
  public asyncMethod() {
    doSomething();
    console.log('using mocked class method');
  }
}

MyComponent.test.tsx

import { MockedSearchBox } from './testUtil.tsx'
import { render } from '@testing-library/react';
import { MyComponent } from './MyComponent';
 
describe('My component', () => {
  jest.mock('./SearchBox', () => {
    return {
      SearchBox: MockedSearchBox
    }
  });

  test('that my component shows text', () => {
    const { getByText } = render(<MyComponent />);
    expext(getByText('Search mock text')).toBeDefined();
  });
});

But this is not working. The original class method is being called even after writing above code. What am I doing wrong?

1 Answer 1

1

You are mocking ./SearchBox module, so you'd better don't extends original SearchBox component. You should create a simple mocked version for SearchBox component.

E.g.

MyComponent.tsx:

import React from 'react';
import { SearchSection } from './SearchSection';

export class MyComponent extends React.Component {
  render() {
    return <SearchSection />;
  }
}

SearchBox.tsx:

import React from 'react';

export class SearchBox extends React.Component {
  private timer: ReturnType<typeof setTimeout> | null = null;

  public asyncmethod() {
    if (this.timer !== null) {
      clearTimeout(this.timer);
    }
    this.timer = setTimeout(() => {
      console.log('doSomething');
    }, 1000);
    console.log('using original class method');
    return 'search real text';
  }

  render() {
    return <div>{this.asyncmethod()}</div>;
  }
}

SearchBoxSection.tsx:

import React from 'react';
import { SearchBox } from './SearchBox';

export class SearchSection extends React.Component {
  render() {
    return <SearchBox />;
  }
}

testUtil.tsx

import React from 'react';

export class MockedSearchBox extends React.Component {
  public asyncMethod() {
    console.log('using mocked class method');
    return 'Search mock text';
  }
  render() {
    return <div>{this.asyncMethod()}</div>;
  }
}

MyComponent.spec.tsx:

import React from 'react';
import { render } from '@testing-library/react';
import { MyComponent } from './MyComponent';

jest.mock('./SearchBox', () => {
  const { MockedSearchBox } = require('./testUtil');

  return {
    SearchBox: MockedSearchBox,
  };
});

describe('My component', () => {
  test('that my component shows text', () => {
    const { getByText } = render(<MyComponent />);
    expect(getByText('Search mock text')).toBeDefined();
  });
});

unit test result:

 PASS  examples/65933863/MyComponent.spec.tsx (9.544 s)
  My component
    √ that my component shows text (59 ms)

  console.log
    using mocked class method

      at MockedSearchBox.asyncMethod (examples/65933863/testUtil.tsx:5:13)

-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |     100 |      100 |     100 |     100 | 
 MyComponent.tsx   |     100 |      100 |     100 |     100 | 
 SearchSection.tsx |     100 |      100 |     100 |     100 | 
 testUtil.tsx      |     100 |      100 |     100 |     100 | 
-------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.973 s
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.