Reputation: 4066
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?
Upvotes: 0
Views: 7179
Reputation: 102207
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
Upvotes: 1