Je suis relativement nouveau en Jest et en test en général. J'ai un composant avec un élément d'entrée:
import * as React from "react";
export interface inputProps{
placeholder: string;
className: string;
value: string;
onSearch: (depID: string) => void;
}
onSearch(event: any){
event.preventDefault();
//the actual onclick event is in another Component
this.props.onSearch(event.target.value.trim());
}
export class InputBox extends React.Component<inputProps, searchState> {
render() {
return (
<input
onChange={this.onSearch} //need to test this
className={this.props.className}
type="text"
value={this.props.value}
placeholder={this.props.placeholder} />
);
}
}
Je veux un test qui vérifie que la variable onChange
de l'élément d'entrée est une fonction qui prend l'attribut value
de l'élément d'entrée en tant que paramètre. Voici à quel point je suis arrivé jusqu'ici:
//test to see the input element's onchange
//returns a function that takes its value as a param
it("onChange param is the same value as the input value", () => {
const mockFn = jest.fn();
const input = enzyme.shallow(<InputBox
value="TestVal"
placeholder=""
className=""
onSearch={mockFn}/>);
input.find('input').simulate('change', { preventDefault() {} });
expect(mockFn.mock.calls).toBe("TestVal");
});
Je pars de la première solution ici Simuler un clic de bouton dans Jest Et: https://facebook.github.io/jest/docs/en/mock-functions.html
Edit: L'exécution de ce qui précède génère l'erreur suivante:
TypeError: Cannot read property 'value' of undefined
La syntaxe de votre extrait de code devrait être:
import React from 'react';
export default class InputBox extends React.Component {
onSearch(event) {
event.preventDefault();
this.props.onSearch(event.target.value.trim());
}
render () { return <input onChange={this.onSearch.bind(this)} />; }
}
Le test échoue car, tout comme vous définissez la fonction preventDefault
sur l'objet événement, vous devez également définir d'autres propriétés utilisées sur la fonction onSearch
.
it('should call onChange prop', () => {
const onSearchMock = jest.fn();
const event = {
preventDefault() {},
target: { value: 'the-value' }
};
const component = enzyme.shallow(<InputBox onSearch={onSearchMock} />);
component.find('input').simulate('change', event);
expect(onSearchMock).toBeCalledWith('the-value');
});
Le code de test précédent doit définir la forme de l'événement, car vous utilisez un rendu peu profond. Si vous souhaitez plutôt vérifier que la valeur d'entrée réelle est utilisée sur votre fonction onSearch
, vous devez essayer un rendu complet avec enzyme.mount
:
it('should call onChange prop with input value', () => {
const onSearchMock = jest.fn();
const component = enzyme.mount(<InputBox onSearch={onSearchMock} value="custom value" />);
component.find('input').simulate('change');
expect(onSearchMock).toBeCalledWith('custom value');
});
J'ai trouvé la solution.
Ainsi, au lieu de transmettre la valeur dans InputBox
, nous devons la passer dans le deuxième paramètre de simulate
comme indiqué ci-dessous. Ensuite, nous vérifions simplement l’égalité avec le premier argument du premier appel à la variable mockFn
. De plus, nous pouvons nous débarrasser de la event.preventDefault()
;
it("onChange param is the same value as the input element's value property", () => {
const mockFn = jest.fn();
const input = enzyme.shallow(<InputBox
value=""
placeholder=""
className=""
onSearch={mockFn}/>);
input.find('input').simulate('change', {target: {value: 'matched'} });
expect(mockFn.mock.calls[0][0]).toBe('matched');
});