简体   繁体   中英

Jest - Call React Component function without Enzyme

I am writing a Test for a React Component Product . I am using plain simple Jest without react-renderer or enzyme and I am aiming to keep it this way for the time being. I need to test a function of a component and havent been able to call it directly through jest. Code given below.

Component:

import React, { Component } from 'react';

class Product extends Component {
    state = {
        heading: `Old Heading`
    };

    changeHeading() {
        this.setState({ heading: `New Heading` });
    }

    render() {
        return (
            <div>
                <p data-testid='heading'> {this.state.heading} </p>
            </div>
        );
    }
}

export default Product;

Jest Test:

import React from 'react';
import { render } from 'react-dom';
// import { act } from 'react-dom/test-utils';
import Product from './Product';


let container = null;

beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
});

afterEach(() => {
    document.body.removeChild(container);
    container = null;
});

describe(`Testing Product Component`, () => {
    it('renders without crashing', () => {
        // act(() => {
        //     render(<Product />, container);
        // });
        const result = render(<Product />, container);
        const heading = container.querySelector("[data-testid='heading']");
        console.log(heading);
        expect(heading).toBe(`Old Heading`);
        result.changeHeading();
        expect(heading).toBe(`New Heading`);
        ReactDOM.unmountComponentAtNode(div);
    });
});

OR

   it('renders without crashing', () => {
        const productComponent = <Product />;
        render(productComponent, container);
        const heading = container.querySelector("[data-testid='heading']");
        console.log(heading);
        expect(heading).toBe(`Old Heading`);
        productComponent.changeHeading();
        expect(heading).toBe(`New Heading`);
        ReactDOM.unmountComponentAtNode(div);
    });

But it didn't worked. How can I access the changeHeading function from the component in my jest test? and call it to change the content of <p> tag?

EDIT

I will reside with react-test-library if I have to for the timebeing. But it would be great if someone can explain the internal workings as well.

Thank you.

To test that, you need a user interaction that calls changeHeading() . In your test, when you do const result = render(<Product />, container); you are storing a reference to the component DOM node.

So, you need to modify your component to be able to have an interaction:

import React, { Component } from 'react';

class Product extends Component {
    state = {
        heading: `Old Heading`
    };

    changeHeading() {
        this.setState({ heading: `New Heading` });
    }

    render() {
        return (
            <div>
                <p data-testid='heading'> {this.state.heading} </p>
                <button onclick={this.changeHeading}></button>
            </div>
        );
    }
}

export default Product;

and your test would be:

import React from 'react';
import { render } from 'react-dom';
import { act } from 'react-dom/test-utils';
import Product from './Product';


let container = null;

beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
});

afterEach(() => {
    document.body.removeChild(container);
    container = null;
});

describe(`Testing Product Component`, () => {
    it('renders without crashing', async () => {
        act(() => {
            render(<Product />, container);
        });

        let heading = container.querySelector("[data-testid='heading']");
        expect(heading).toBe(`Old Heading`);

        const button = container.querySelector('button');

        await act(async () => {
            button.dispatchEvent(new MouseEvent('click', { bubbles: true }));
        });

        heading = container.querySelector("[data-testid='heading']");
        expect(heading).toBe(`New Heading`);
        ReactDOM.unmountComponentAtNode(div);
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM