Сделать шутку / энзимный тест ждать контекста - PullRequest
0 голосов
/ 06 марта 2020

Мне трудно делать тесты, которые ждут нового состояния из контекста. Вот простое приложение, которое показывает загрузчик, пока пользователь не получит:

(я знаю, что весь код не нужен для того, чтобы приложение делало то, что оно делает, но больше отражает то, как у меня реализация в реальном проекте)

export const Greeting: React.FC<{}> = () => {
  const { loading, user } = useUserContext();

  return (
    <div>
      {loading ? (
        <CircularProgress />
      ) : (
        <h1>
          Hello {user.firstname} {user.lastname}
        </h1>
      )}
    </div>
  );
};

и вот тест:

import React from "react";
import Adapter from "enzyme-adapter-react-16";
import Enzyme, { mount } from "enzyme";
import { Greeting } from "./Greeting";
import { UserContextProvider } from "./UserContext";

Enzyme.configure({ adapter: new Adapter() });

describe("Test of <Greeting />", () => {
  it(">>>> should show spinner on loading = true", () => {
    const wrapper = mount(<Greeting />);
    expect(wrapper.find("ForwardRef(CircularProgress)").exists()).toEqual(true);
  });
  it(">>>> should show greeting on loading = false", async () => {
    const wrapper = mount(
      <UserContextProvider>
        <Greeting />
      </UserContextProvider>
    );
    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve(wrapper);
      }, 5000);
    });
    promise.then((res: Enzyme.ReactWrapper<any>) => {
      console.log(res.debug());
      expect(res.find("h1").text()).toEqual("Hello Bob Testman");
    });
  });
});

Ссылка на коды и окно: https://codesandbox.io/embed/modern-sea-tx3ro?fontsize=14&hidenavigation=1&theme=dark

Любой идеи о том, как решить эту проблему?

Обновление Благодаря @Noix это прекрасно работает

it(">>>> should show greeting on loading = false", async () => {
const wrapper = mount(
  <UserContextProvider>
    <Greeting />
  </UserContextProvider>
);
const promise = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      wrapper.update();
      resolve(wrapper);
    }, 3000);
  });
};
return promise().then((res: Enzyme.ReactWrapper<any>) => {
  console.log(res.debug());
  expect(res.find("h1").text()).toEqual("Hello Bob Testman");
});

1 Ответ

0 голосов
/ 06 марта 2020

Полагаю, у вас возникли проблемы, потому что Джест заканчивает тест до того, как ваше обещание будет выполнено. Попробуйте добавить выражение «возврат» перед вашим «обещанием. Потом», чтобы Джест мог дождаться окончания вашего обещания, прежде чем закончить тест.

В соответствии с этим:

https://jestjs.io/docs/en/asynchronous.html

Jest не ожидает возврата обратного вызова, за исключением случаев, когда:

опция 1: вы добавляете done в качестве аргумента к своей функции "it", поэтому тест разрешается только тогда, когда Вы вызываете функцию done (в этом случае вам нужно использовать try catch, чтобы быть уверенным, что всегда сделано done)

опция 2: вы используете обещание, это самое простое, но никогда не забывайте возвращать свое обещание :)

вариант 3: вы можете использовать выражение «ожидание» для своего обещания, но ТОГДА вы должны использовать ключевое слово asyn c в своей функции «it»

Так что в вашем случае вы можете либо дождитесь своего обещания дождаться его окончания, либо просто верните свое обещание. Надеюсь, это поможет.

Приветствия:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...