Nie mam pojęcia, jak uzyskać dostęp do <input>
wartości podczas używania mount
. Oto, co mam jako mój test:
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();
});
Konsola drukuje undefined
. Ale jeśli trochę zmodyfikuję kod, działa:
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();
});
Tyle że, oczywiście, input.simulate
linia zawodzi, ponieważ używam render
teraz. Potrzebuję obu, aby działać poprawnie. Jak to naprawić?
EDYCJA :
Powinienem wspomnieć, że <EditableText />
nie jest elementem kontrolowanym. Ale kiedy przechodzę defaultValue
do <input />
, wydaje się , że ustawia wartość. Drugi blok kodu powyżej wypisuje wartość i podobnie, jeśli sprawdzę element wejściowy w Chrome i wpiszę $0.value
w konsoli, pokazuje oczekiwaną wartość.
źródło
input.render()
jestreact-dom
renderowany. To jest to: airbnb.io/enzyme/docs/api/ShallowWrapper/render.htmlshallow()
tym z jakiegoś powodu nie działa ...focus
zdarzenie wyzwala metodę, która próbuje się odwołaćthis.refs.input
, co kończy się niepowodzeniem. Ale kiedy zamieniam sięshallow
namount
, działa zgodnie z oczekiwaniami. Głównie ... (jeszcze jeden problem z symulacją klawisza ESC)render(<EditableText defaultValue="Hello" />)
. Myślę, że Twój przypadek użycia jest bardziej wyspecjalizowany niż myślałem; Widzę, że zajmuje się uwagą tylko z ustawieniem wartości wejściowej, ale z fokusem i „anulowaniem zmian”. Byłoby wspaniale, gdybyś mógł stworzyć plunkera .W przypadku Enzyme 3 , jeśli chcesz zmienić wartość wejściową, ale nie musisz uruchamiać
onChange
funkcji, możesz po prostu zrobić to (node
właściwość została usunięta ):wrapper.find('input').instance().value = "foo";
Możesz użyć
wrapper.find('input').simulate("change", { target: { value: "foo" }})
do wywołania,onChange
jeśli masz do tego właściwość (np. Dla kontrolowanych komponentów).źródło
NOTE: can only be called on a wrapper instance that is also the root instance.
- z dokumentacji na airbnb.io/enzyme/docs/api/ShallowWrapper/instance.htmlinstance()
można wywołać w dowolnym opakowaniu podrzędnym, jeśli zostało wyrenderowane przezmount
.Rozumiem. (zaktualizowana / ulepszona wersja)
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(); });
źródło
mount()
nie wstawiamy komponentów do DOM. Więc nie mogą się skupić. Musimy dodać element DOM i użyćcontext
opcjimount()
input.prop('value')
Tak wiele różnych opinii tutaj. Jedyną rzeczą, która działała dla mnie, nie było żadne z powyższych, to było używanie
input.props().value
. Mam nadzieję że to pomogło.źródło
input.prop('value')
jeśli znasz nazwę swojego klucza rekwizytu.Używam aplikacji Create-React-App, która jest domyślnie dostarczana z jest i enzymem 2.7.0.
To zadziałało dla mnie:
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();
źródło
Żadne z powyższych nie działało dla mnie. Oto, co zadziałało dla mnie w Enzyme ^ 3.1.1:
input.instance().props.onChange(({ target: { value: '19:00' } }));
Oto reszta kodu kontekstu:
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);
źródło
Używam Reaguj z TypeScript i działały dla mnie następujące
wrapper.find('input').getDOMNode<HTMLInputElement>().value = 'Hello'; wrapper.find('input').simulate('change');
Bezpośrednie ustawienie wartości
wrapper.find('input').instance().value = 'Hello'`
powodowało ostrzeżenie dotyczące kompilacji.
źródło
To działa dla mnie przy użyciu enzymu 2.4.1:
const wrapper = mount(<EditableText defaultValue="Hello" />); const input = wrapper.find('input'); console.log(input.node.value);
źródło
console.log
z obiektu i przeszukiwałem (pod-) właściwości, aby uzyskać to, czego potrzebowałem. Robiąc to, często kończyłem na używaniu.node
w jakiejś formie, tak jak masz. Jednak nie przypominam sobie,.node
aby ktoś o tym wspominał w oficjalnej dokumentacji, co sugeruje, że może się to zmieniać / przerywać między wydaniami, ponieważ nie jest oficjalnie częścią reklamowanego publicznie interfejsu API. Często wydaje się, że istnieją alternatywy. np .input.node.value
===input.get(0).value
. Więc.node
może zadziałać i podejrzewam, że czasami zapewni dobry hack, ale używaj go ostrożnie.oto mój kod ..
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)
Zaktualizowałem swój DOM za pomocą
componentname.update()
A następnie sprawdzam walidację przycisku przesyłania (wyłącz / włącz) o długości 10 cyfr.źródło
W moim przypadku korzystałem z wywołań zwrotnych,
<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}} >
Aby uzyskać wartość. Więc enzym nie zmieni wartości this._username.
Musiałem więc:
login.node._username.value = "[email protected]"; user.simulate('change'); expect(login.state('mailValid')).toBe(true);
Aby móc ustawić wartość, wywołaj zmianę. A potem potwierdzaj.
źródło
To zadziałało dla mnie:
let wrapped = mount(<Component />); expect(wrapped.find("input").get(0).props.value).toEqual("something");
źródło
Na wypadek, gdyby ktoś miał problemy, zauważyłem, że działa dla mnie następujący
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 2
Wygląda na to, że musisz najpierw zdefiniować, co dzieje się w zdarzeniu zmiany, a następnie to zasymulować (zamiast symulować zdarzenie zmiany za pomocą danych)
źródło
Rozwiązałem w bardzo prosty sposób:
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); });
Twoje zdrowie
źródło
Żadne z powyższych rozwiązań nie zadziałało, ponieważ korzystałem z Formika i musiałem zaznaczyć pole „dotknięte” wraz ze zmianą wartości pola. Poniższy kod zadziałał dla mnie.
const emailField = orderPageWrapper.find('input[name="email"]') emailField.simulate('focus') emailField.simulate('change', { target: { value: '[email protected]', name: 'email' } }) emailField.simulate('blur')
źródło
Do ustawienia wartości używam metody setValue [ https://vue-test-utils.vuejs.org/api/wrapper/#setvalue-value] Wrappera .
inputA = wrapper.findAll('input').at(0) inputA.setValue('123456')
źródło
.simulate()
jakoś nie działa dla mnie, działało po prostu uzyskując dostęp donode.value
bez konieczności dzwonienia.simulate()
; w Twoim przypadku: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
Mam nadzieję, że to pomoże innym!
źródło
.node
używać.instance()
lub.getDOMNode()
, zależy od tego, czy użyłeś wyniku jako ReactElement czy DOMComponent.