Estoy confundido acerca de cómo acceder al <input>valor cuando lo uso mount. Esto es lo que tengo como prueba:
it('cancels changes when user presses esc', done => {
const wrapper = mount(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.render().attr('value'));
input.simulate('focus');
done();
});
Se imprime la consola undefined. Pero si modifico ligeramente el código, funciona:
it('cancels changes when user presses esc', done => {
const wrapper = render(<EditableText defaultValue="Hello" />);
const input = wrapper.find('input');
console.log(input.val());
input.simulate('focus');
done();
});
Excepto, por supuesto, que la input.simulatelínea falla ya que la estoy usando renderahora. Necesito que ambos funcionen correctamente. ¿Cómo puedo solucionar esto?
EDITAR :
Debo mencionar <EditableText />que no es un componente controlado. Pero cuando paso defaultValueen <input />, al parecer para ajustar el valor. El segundo bloque de código anterior imprime el valor y, de la misma manera, si inspecciono el elemento de entrada en Chrome y escribo $0.valueen la consola, muestra el valor esperado.
fuente

input.render()esreact-domrender. Es esto: airbnb.io/enzyme/docs/api/ShallowWrapper/render.htmlshallow()no funciona por alguna razón ... elfocusevento activa un método que intenta hacer referenciathis.refs.input, que falla. Pero cuando intercambiarshallowparamount, funciona como se esperaba. Principalmente ... (un problema más con la simulación de la tecla ESC)render(<EditableText defaultValue="Hello" />). Creo que su caso de uso es más especializado de lo que pensaba; Veo que se ocupa de la nota solo con establecer el valor de entrada pero con el enfoque y "cancelar cambios". Sería genial si pudieras crear un plunker .Con la Enzima 3 , si necesita cambiar un valor de entrada pero no necesita
onChangeactivar la función, simplemente puede hacer esto (lanodepropiedad ha sido eliminada ):wrapper.find('input').instance().value = "foo";Puede usar
wrapper.find('input').simulate("change", { target: { value: "foo" }})para invocaronChangesi tiene un accesorio para eso (es decir, para componentes controlados).fuente
NOTE: can only be called on a wrapper instance that is also the root instance.- de los documentos en airbnb.io/enzyme/docs/api/ShallowWrapper/instance.htmlinstance()se puede llamar en cualquier contenedor secundario si se procesó a través demount.Entendido. (versión actualizada / mejorada)
it('cancels changes when user presses esc', done => { const wrapper = mount(<EditableText defaultValue="Hello" />); const input = wrapper.find('input'); input.simulate('focus'); input.simulate('change', { target: { value: 'Changed' } }); input.simulate('keyDown', { which: 27, target: { blur() { // Needed since <EditableText /> calls target.blur() input.simulate('blur'); }, }, }); expect(input.get(0).value).to.equal('Hello'); done(); });fuente
mount()no inserta componentes en el DOM. Entonces, no pueden recibir atención. Tenemos que agregar un elemento DOM y usar lacontextopción paramount()input.prop('value')Hay muchas opiniones diferentes aquí. Lo único que funcionó para mí fue nada de lo anterior, estaba usando
input.props().value. Espero que eso ayude.fuente
input.prop('value')si conoce el nombre de su clave de apoyo.Estoy usando create-react-app que viene con jest por defecto y enzima 2.7.0.
Esto funcionó para mí:
const wrapper = mount(<EditableText defaultValue="Hello" />); const input = wrapper.find('input')[index]; // where index is the position of the input field of interest input.node.value = 'Change'; input.simulate('change', input); done();fuente
Ninguno de los anteriores funcionó para mí. Esto es lo que funcionó para mí en Enzyme ^ 3.1.1:
input.instance().props.onChange(({ target: { value: '19:00' } }));Aquí está el resto del código para el contexto:
const fakeHandleChangeValues = jest.fn(); const fakeErrors = { errors: [{ timePeriod: opHoursData[0].timePeriod, values: [{ errorIndex: 2, errorTime: '19:00', }], }], state: true, }; const wrapper = mount(<AccessibleUI handleChangeValues={fakeHandleChangeValues} opHoursData={opHoursData} translations={translationsForRendering} />); const input = wrapper.find('#input-2').at(0); input.instance().props.onChange(({ target: { value: '19:00' } })); expect(wrapper.state().error).toEqual(fakeErrors);fuente
Estoy usando react con TypeScript y lo siguiente funcionó para mí
wrapper.find('input').getDOMNode<HTMLInputElement>().value = 'Hello'; wrapper.find('input').simulate('change');Establecer el valor directamente
wrapper.find('input').instance().value = 'Hello'`me estaba provocando una advertencia de compilación.
fuente
Esto me funciona usando la enzima 2.4.1:
const wrapper = mount(<EditableText defaultValue="Hello" />); const input = wrapper.find('input'); console.log(input.node.value);fuente
console.logbuscaba un objeto y buscaba (sub) propiedades para obtener lo que necesitaba. Al hacerlo, a menudo terminé usando.nodede alguna forma, como tú. Sin embargo, no recuerdo haber.nodesido mencionado en ninguna de la documentación oficial, lo que sugiere que podría cambiar / interrumpirse entre lanzamientos, ya que no forma parte oficialmente de la API anunciada públicamente. Además, a menudo parece haber alternativas. por ejemploinput.node.value===input.get(0).value. Entonces,.nodepodría funcionar, y sospecho que a veces proporcionará un buen truco, pero utilícelo con precaución.aquí está mi código ..
const input = MobileNumberComponent.find('input') // when input.props().onChange({target: { id: 'mobile-no', value: '1234567900' }}); MobileNumberComponent.update() const Footer = (loginComponent.find('Footer')) expect(Footer.find('Buttons').props().disabled).equals(false)He actualizado mi DOM con
componentname.update()Y luego verifiqué la validación del botón de envío (deshabilitar / habilitar) con una longitud de 10 dígitos.fuente
En mi caso, estaba usando devoluciones de llamada de referencia,
<input id="usuario" className="form-control" placeholder="Usuario" name="usuario" type="usuario" onKeyUp={this._validateMail.bind(this)} onChange={()=> this._validateMail()} ref={(val) =>{ this._username = val}} >Para obtener el valor. Así que la enzima no cambiará el valor de this._username.
Entonces tuve que:
login.node._username.value = "[email protected]"; user.simulate('change'); expect(login.state('mailValid')).toBe(true);Para poder establecer el valor, llame al cambio. Y luego afirmar.
fuente
Esto funcionó para mí:
let wrapped = mount(<Component />); expect(wrapped.find("input").get(0).props.value).toEqual("something");fuente
En caso de que alguien tenga dificultades, encontré lo siguiente que me funciona
const wrapper = mount(<NewTask {...props} />); // component under test const textField = wrapper.find(TextField); textField.props().onChange({ target: { value: 'New Task 2' } }) textField.simulate('change'); // wrapper.update() didn't work for me, need to find element again console.log(wrapper.find(TextField).props()); // New Task 2Parece que primero debe definir lo que sucede en el evento de cambio y luego simularlo (en lugar de simular el evento de cambio con datos)
fuente
Resolví de una manera muy simple:
const wrapper: ShallowWrapper = shallow(<ProfileViewClass name: 'Sample Name' />);<input type='text' defaultValue={props.name} className='edituser-name' />wrapper.find(element).props().attribute-name:it('should render user name', () => { expect(wrapper.find('.edituser-name').props().defaultValue).toContain(props.name); });Salud
fuente
Ninguna de las soluciones anteriores funcionó para mí porque estaba usando Formik y necesitaba marcar el campo como "tocado" junto con cambiar el valor del campo. El siguiente código funcionó para mí.
const emailField = orderPageWrapper.find('input[name="email"]') emailField.simulate('focus') emailField.simulate('change', { target: { value: '[email protected]', name: 'email' } }) emailField.simulate('blur')fuente
Utilizo el método setValue [ https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] de Wrapper para establecer el valor.
inputA = wrapper.findAll('input').at(0) inputA.setValue('123456')fuente
.simulate()no funciona para mí de alguna manera, lo hice funcionar con solo accedernode.valuesin necesidad de llamar.simulate(); en tu caso:const wrapper = mount(<EditableText defaultValue="Hello" />); const input = wrapper.find('input').at(0); // Get the value console.log(input.node.value); // Hello // Set the value input.node.value = 'new value'; // Get the value console.log(input.node.value); // new value¡Espero que esto ayude a los demás!
fuente
.nodedebe usar.instance()o.getDOMNode(), depende de si usó el resultado como ReactElement o DOMComponent.