Description
When trying to set value prop on mounted component in a Jest and Enzyme test, value doesn't show up in props before or after trying to set value prop on text input.
Component code:
import React, { Component } from "react";
class AddItemBar extends Component {
constructor(props) {
super(props);
this.addItem = this.addItem.bind(this);
}
addItem() {
let itemVal = this.refs.addItemInput.value;
if (itemVal.trim() !== "") {
this.props.add(itemVal);
}
}
render() {
return (
<div className="add-item-bar">
<input
type="text"
ref="addItemInput"
placeholder="Add New Item"
/>
<button value="Send" onClick={this.addItem}>
Add
</button>
</div>
);
}
}
export default AddItemBar;
Test code:
import React from "react";
import { shallow, mount, render } from "enzyme";
import ReactDOM from "react-dom";
import AddItemBar from "./AddItemBar";
it("calls addItem once", () => {
//const wrapper = shallow(<AddItemBar add={() => {}} />);
const mockCallBack = jest.fn();
const spy = jest.spyOn(AddItemBar.prototype, "addItem");
const wrapper = mount(<AddItemBar add={mockCallBack} />);
//const instance = wrapper.instance();
//instance.addItem = jest.fn();
const textInput = wrapper.find("input");
const button = wrapper.find("button");
//jest.spyOn(instance, "addItem");
textInput.props().value = "fold laundry";
//textInput.getElement().value = "fold laundry";
//console.log(wrapper.find("input").props());
//textInput.simulate("change");
//textInput.simulate("change", { target: { value: "fold laundry" } });
//wrapper.update();
//textInput.instance().value = "fold laundry";
button.simulate("click");
//expect(instance.addItem).toHaveBeenCalled();
expect(spy).toHaveBeenCalled();
console.log(textInput.props());
expect(wrapper.find("input").prop("value")).toEqual("fold laundry");
//expect(mockCallBack).toHaveBeenCalled();
});
});
Expected behavior
I'm new to Enzyme and Jest. What I'm trying to accomplish is writing a test that sets a value to a text input, simulates a click on a button, then assert if a function (spy variable) is called based on the value of the text input. I plan on asserting the spy is called if the text input is not null, empty or white space, and spy is not called if null, empty or white space. I've have spent hours looking through stack overflow and enzyme issues reading answers but none have worked for me (as evidenced by commented code out above). I must be missing something.
Desktop:
Enzyme and React info:
Additional context
I do not have a change handler function on my text input, which if I understand correctly, is why a simulate change event never worked for setting the value to the text input. Also, when I console.log(textInput.props()); both before and after trying to set a value, I never see the value prop on the textInput, I don't know if this is a red herring or not.
Your input doesn't have a value prop. if you want to get at the DOM node, and get its value prop, you can use .getDOMNode().
Happy to reopen if this doesn't answer the question.
Just ran my test code with this. Looks like getDOMNode().value did the trick. Thank you very much for your response!
Note that in TypeScript, I had to cast the return value of getDOMNode() to HTMLInputElement or else it would complain that Property 'value' does not exist on type 'Element'. So, I did this:
const domNode = wrapper.find("input").getDOMNode() as HTMLInputElement
domNode.value = "myvalue"
getDOMNode() is declared a generic method getDOMNode<T>(), so the following also works:
const domNode = wrapper.find("input").getDOMNode<HTMLInputElement>()
domNode.value = "myvalue"
Most helpful comment
Note that in TypeScript, I had to cast the return value of
getDOMNode()toHTMLInputElementor else it would complain thatProperty 'value' does not exist on type 'Element'.So, I did this: