dimanche 22 décembre 2019

jest.fn is not called while submitting form (typescript)

I have a component called Tasks that simply render a form and a list of fetched tasks. The form itself has its logic separate in another component called AddTaskForm. I am now trying to test when a form is submitted but I am failing with an error that jest.fn has zero number of calls.

Here is my current logic.

Tasks Component

export interface TasksProps {
    categories: Category[];
    getCategories: Function;
    deleteTask: typeof deleteTask;
    addTask: typeof addTask;
}

export class Tasks extends React.Component<TasksProps> {
    constructor(props: TasksProps) {
        super(props);

        this.onSubmit = this.onSubmit.bind(this);
    }
    componentDidMount() {
        this.props.getCategories();
    }

    onDelete(id: string) {
        this.props.deleteTask(id);
    }

    onSubmit(newTask: Task) {
        this.props.addTask(newTask);
    }
  render() {
        return (
            <div>
                <h1>Tasks Component</h1>
                <AddTaskForm
                    onSubmit={this.onSubmit}
                    categories={this.props.categories}
                />
             // the p tags are not the actual code, just for simplifying
             <p>Task 1</p>
             <p>Task 2</p>
             </div>
}

AddTaskForm Component

interface AddTaskFormProps {
    categories: Category[];
    onSubmit(newTask: Task): void;
}

export class AddTaskForm extends React.Component<AddTaskFormProps> {
    constructor(props: AddTaskFormProps) {
        super(props);

        this.onSubmit = this.onSubmit.bind(this);
    }
    state: Task = {
        id: 'default-id',
        title: '',
        categoryTitle: '',
        error: null
    };

    onSubmit(e: any) {
        e.preventDefault();
        let title = e.target.elements[0].value;
        let categoryTitle = e.target.elements[1].value;
        let id = uuid();
        if (title && categoryTitle !== 'Select an option') {
            this.setState(
                () => {
                    return {
                        title,
                        categoryTitle,
                        id,
                        error: null
                    };
                },
                () => this.props.onSubmit(this.state)
            );
            e.target.elements[0].value = '';
            e.target.elements[1].value = 'Select an option';
        } else if (
            !title ||
            !categoryTitle ||
            categoryTitle === 'Select an option'
        ) {
            this.setState(() => {
                return {
                    error:
                        'Please make sure you you have enetered a Task title and selected a category'
                };
            });
        }
    }
    render() {
        return (
            <div>
                {this.state.error && (
                    <p className='error'>{this.state.error}</p>
                )}
                <form className='add_task_form' onSubmit={this.onSubmit}>
                    <label>Task Title:</label>
                    <input type='text'></input>
                    <label>Task Category:</label>
                    <select>
                        <option>Select an option</option>
                        {this.props.categories.map((category, i: number) => {
                            return <option key={i}>{category.name}</option>;
                        })}
                    </select>
                    <input type='submit' value='Add Task' />
                </form>
            </div>
        );
    }
}

My test for the form submission:

test('AddTaskForm should correctly adds a task to the Tasks page on submit', () => {
    const onSubmit = jest.spyOn(Tasks.prototype, 'onSubmit');
    wrapper.find('AddTaskForm').prop('onSubmit')!(newTask as any);
    const { title, id } = newTask;
    expect(onSubmit).toHaveBeenLastCalledWith({ title, id });
});

Appreciate any assistance.

Aucun commentaire:

Enregistrer un commentaire