开玩笑-调用没有酶的React Component函数

问题描述

我正在编写一个React组件Product的测试。我正在使用不带react-rendererenzyme的简单简单的Jest,并且我的目标是暂时保持这种方式。我需要测试组件的功能,还不能通过玩笑直接调用它。代码如下。

组件:

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测试:

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);
    });

但是没有用。在玩笑测试中如何从组件访问changeheading函数?并调用它来更改<p>标签内容

编辑

如果需要的话,我将驻留在react-test-library中。但是,如果有人也能解释内部工作原理,那将是很好的。

谢谢。

解决方法

要对此进行测试,您需要调用changeHeading()的用户交互。在测试中,当您执行const result = render(<Product />,container);时,将存储对组件DOM节点的引用。

因此,您需要修改组件以进行交互:

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;

您的测试将是:

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);
    });
});