如何断言该方法被调用

How to assert that method is called

这是我的表格:

import { useState } from "react"
import { Form, Button, Row, Col } from "react-bootstrap"
import { actions as parametersActions } from "../../actions/ParametersActions"
import { connect } from "react-redux"

export const Parameters = props => {

    const [birthdate, setBirthdate] = useState("")
    const [height, setHeight] = useState("")

    const handleForm = (e) => {
        if (e.target.id === 'birthdate') {
            setBirthdate(e.target.value)
        }
        if (e.target.id === 'height') {
            setHeight(e.target.value)
        }
    }

    const handleSubmit = (e) => {
        e.preventDefault()
        const payload = {
            birthdate: birthdate,
            height: height
        }
        props.post(payload)
    }

    return (
        <Row className="justify-content-md-center">
            <Col xs lg="4">
                <Form>
                    <Form.Group controlId="birthdate">
                        <Form.Label>Data di nascita</Form.Label>
                        <Form.Control type="text" placeholder="Inserisci data di nascita" value={birthdate} onChange={handleForm} />
                    </Form.Group>
                    <Form.Group controlId="height">
                        <Form.Label>Altezza</Form.Label>
                        <Form.Control type="text" placeholder="Altezza" value={height} onChange={handleForm} />
                    </Form.Group>
                    <div className="d-grid gap-2">
                        <Button variant="primary" onClick={handleSubmit}>
                            Salva
                        </Button>
                    </div>
                </Form>
            </Col>
        </Row>
        
    )
}

export const mapStateToProps = (state) => {
    return {
        isLoading: state.parameters.isLoading
    }
}

export const mapDispatchToProps = (dispatch) => {
    return {
        post: (data) => dispatch(parametersActions.post(data))
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Parameters)

这是我的测试:

import { render, screen, fireEvent } from '@testing-library/react'
import thunk from 'redux-thunk'
import configureMockStore from 'redux-mock-store'
import Parameters from '../../../presentationals/forms/Parameters'
import { action as parametersActions } from '../../../actions/ParametersActions'


describe('Parameters form', () => {

    it('Can store new parameters', async () => {

        const middlewares = [thunk]
        const mockStore = configureMockStore(middlewares)
      
        const initialState = {
            parameters: {
                isLoading: false,
            },
            post: (data) => dispatch(parametersActions.post(data))
        }
        const store = mockStore(initialState)

        render(<Parameters store={store} />)
        const birthdate = screen.getByText(/nascita/i)
        expect(birthdate).toBeInTheDocument()
      
        const height = screen.getByText(/altezza/i)
        expect(height).toBeInTheDocument()
      
        fireEvent.change(screen.getByLabelText(/nascita/i), {
            target: {value: '1990-12-31'},
        })
      
        fireEvent.change(screen.getByLabelText(/altezza/i), {
            target: {value: '170'},
        })

        fireEvent.click(screen.getByText(/salva/i))
        // how can I test here?
        
    })

})

我想测试一下

  1. handleSubmit被称为
  2. props.post()被称为

如何添加该测试?

您应该测试触发提交事件的结果,而不是测试是否已调用 handleSubmit。在这种情况下,这可能意味着验证是否已发货。

当使用 React-Testing-Library 时,不要测试内部实现细节,而是测试组件的 API,在这种情况下,post prop 回调函数。

  1. 导入并测试 unconnected 组件,你可以轻松模拟 redux 提供的 prop 值
  2. 模拟一个 post 属性函数
  3. 与 UI
  4. 互动
  5. 断言调用了 post prop 函数 (toHaveBeenCalled)

代码:

import { render, screen, fireEvent } from '@testing-library/react';
import { Parameters } from '../../../presentationals/forms/Parameters'
import { action as parametersActions } from '../../../actions/ParametersActions';


describe('Parameters form', () => {
  it('Can store new parameters', async () => {
    const postMock = jest.fn();             // <-- create mock callback

    render(<Parameters post={postMock} />); // <-- pass mock as prop

    ...

    fireEvent.click(screen.getByText(/salva/i));
    expect(postMock).toHaveBeenCalled();    // <-- assert mock was called
  });
});

如果需要,您可以使用 toHaveBeenCalledWith 断言特定值已传递给回调。

expect(postMock).toHaveBeenCalledWith({
  birthdate: '1990-12-31',
  height: '170',
});