Точное решение моей проблемы в следующем коде (скопируйте и вставьте в JS файл, чтобы увидеть, как он работает).
Что нужно отметить:
- I необходимо использовать функцию waitUntil из библиотеки asyn c -wait-till . Сам по себе fetch-mock не предоставляет возможности для тестирования асин c кода.
- Мне нужно было добавить некрасивый хак в global.document.createRange из-за некоторой проблемы со всплывающей подсказкой с response- bootstrap - typeahead и jest.
- используйте waitUntil для ожидания изменений внутреннего состояния компонента
- Очень важно вызвать wrapper.update () для обновления DOM впоследствии.
..
import React, {Component} from 'react';
import waitUntil from 'async-wait-until';
import {mount} from "enzyme";
import fetchMock from "fetch-mock";
import {AsyncTypeahead} from "react-bootstrap-typeahead";
describe('Autocomplete Tests ', () => {
test(' Asynch AutocompleteInput ', async () => {
class AsyncTypeaheadExample extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
isLoading: false,
finished: false
};
}
render() {
return (<AsyncTypeahead
isLoading={this.state.isLoading}
onSearch={query => {
this.setState({isLoading: true});
fetch("http://www.myHTTPenpoint.com")
.then(resp => resp.json())
.then(json => this.setState({
isLoading: false,
options: json.items,
finished: true
}));
}}
options={this.state.options}
labelKey={option => `${option.stateName}`}
/>)
}
}
const url = "http://www.myHTTPenpoint.com"
fetchMock
.reset()
.get(
url,
{
items: [
{id: 1, stateName: "Alaska"},
{id: 2, stateName: "Alabama"}
]
},
);
let Compoment =
<AsyncTypeaheadExample/>
// ugly hacky patch to fix some tooltip bug
// https://github.com/mui-org/material-ui/issues/15726
global.document.createRange = () => ({
setStart: () => {
},
setEnd: () => {
},
commonAncestorContainer: {
nodeName: 'BODY',
ownerDocument: document,
},
});
let wrapper = mount(Compoment);
let sel = wrapper.find(".rbt-input-main").at(0)
sel.simulate('click');
sel.simulate('change', {target: {value: "al"}});
expect(wrapper.find(".rbt-input-main").at(0).getElement().props.value).toBe("al")
//now the async stuff is happening ...
await waitUntil(() => {
return wrapper.state().finished === true;
}, 3000); //wait about 3 seconds
wrapper.update() //need to update the DOM!
expect(wrapper.find(".dropdown-item").length).toBe(2) //but get just 1 element "Type to Search..."
})
});
ОБНОВЛЕНИЕ
Я также могу сравнивать элементы обертки, а не делать прямое сравнение состояния:
//now the async stuff is happening ...
await waitUntil(() => {
wrapper.update() //need to update the DOM!
return wrapper.find(".dropdown-item").length > 1
}, 3000); //wait about 3 seconds
Это, вероятно, лучше, потому что это означает, что мне не нужно знать о компонентах компонентов.