Насколько я понял, вы пытаетесь дождаться разрешения обещания, которое «скрыто» внутри вашего метода componentDidMount ().
expect(renderedComponent.find("users").length).toEqual(1);
не будет работать на мой взгляд в этом контексте, потому что find () пытается выбрать элементы DOM. Если вы хотите проверить состояние, вам нужно использовать state () :
expect(renderedComponent.state("users").length).toEqual(1);
Тем не менее, вам придется найти правильный способ дождаться разрешения обещания:
Чтобы сослаться на предыдущие посты и комментарии, я не вижу никакого эффекта в использовании async / await в сочетании с любым из ферментных методов (обновление, экземпляр или что-либо еще. Документы фермента также не дают подсказки в этом направлении, так как разрешение обещания - не работа фермента).
Единственный надежный, чистый и ( jest-default ) способ продвижения вперед - это смесь разных подходов. Вот ваш код немного изменился:
// component --users
export default class Users extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.getUsers = this.getUsers.bind(this);
}
/*does an api request to get the users*/
/*async await used to handle the asynchronous behaviour*/
async getUsers() {
// Promise is resolved and value is inside of the resp const.
try {
const resp = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
if (resp.status === 200) {
const users = resp.data;
/* mapped user data to just get id and username*/
const userdata = users.map(user => {
var userObj = {};
userObj["id"] = user.id;
userObj["username"] = user.username;
return userObj;
});
return userdata;
}
} catch (err) {
console.error(err);
}
}
componentDidMount() {
// store the promise in a new field, not the state since setState will trigger a rerender
this.loadingPromise = this.getUsers().then(users => this.setState({users: users}));
}
/*****************************************************************/
//props(userid ,username) are passed so that api call is made for
//getting posts of s psrticular user .
/*****************************************************************/
render() {
if (!this.state.users) {
return (
<div className="usersWrapper">
<img className="loading" src="/loading.gif" alt="Loading.."/>
</div>
);
}
return (
<div className="usersWrapper">
{this.state.users.map(user => (
<div key={user.id}>
<Posts username={user.username} userid={user.id}/>
</div>
))}
</div>
);
}
}
//axios.js-mockaxios
export default {
get: jest.fn(() => Promise.resolve({data: {}}))
};
//users.test.js
describe("Users", () => {
describe("componentDidMount", () => {
it("sets the state componentDidMount",() => {
mockAxios.get.mockImplementationOnce(
() =>
Promise.resolve({
users: [
{
id: 1,
username: "Bret"
}
]
}) //promise
);
const renderedComponent = shallow(<Users/>);
//Jest will wait for the returned promise to resolve.
return renderedComponent.instance().loadingPromise.then(() => {
expect(renderedComponent.state("users").length).toEqual(1);
});
});
});
});
Проводя некоторые исследования, я натолкнулся на эту запись : Если честно, я не знаю, хорошая ли это идея, но она работает в моих асинхронных тестах, и она избегает дополнительной ссылки на обещание в вашем компоненте. Так что не стесняйтесь попробовать это тоже!