简体   繁体   English

让笑话/酶测试等待上下文

[英]Make jest/enzyme test wait for context

I have a hard time making tests that are waiting for a new state from context.我很难进行从上下文中等待新状态的测试。 Here is a simple app that is showing a loader until user is fetched:这是一个简单的应用程序,它在获取用户之前显示加载器:

(I know all of the code isn't necessary in order to make the application do what it does, but it reflects more how I have an implementation in a real project) (我知道为了让应用程序做它所做的事情,所有的代码都不是必需的,但它更多地反映了我在实际项目中的实现方式)

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

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

and here's the test:这是测试:

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");
    });
  });
});

Link to codesandbox: https://codesandbox.io/embed/modern-sea-tx3ro?fontsize=14&hidenavigation=1&theme=dark代码和盒子链接: https ://codesandbox.io/embed/modern-sea-tx3ro ? fontsize =14& hidenavigation =1& theme = dark

Any ideas on how to solve this?关于如何解决这个问题的任何想法?

Update Thanks to @Noix this works perfectly更新感谢@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");
});

I believe you're having trouble because Jest ends the test before your promise is completed.我相信您遇到了麻烦,因为 Jest 在您的承诺完成之前就结束了测试。 Try adding the statement "return" before your "promise.then" so Jest will be able to wait for your promise to end before ending the test.尝试在“promise.then”之前添加语句“return”,这样 Jest 将能够在结束测试之前等待您的承诺结束。

According to this :根据这个 :

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

Jest doesn't wait the callback return except if : Jest 不会等待回调返回,除非:

option 1 : you add done as argument to your function "it", so the test only resolve when you call the function done (in this case you need to use a try catch to be sure done is always called)选项 1:将 done 作为参数添加到函数“it”中,因此测试仅在调用函数 done 时解析(在这种情况下,您需要使用 try catch 以确保始终调用 done)

option 2 : you use a promise, it's the simpliest but never forget to return your promise :)选项 2 :您使用承诺,这是最简单的,但永远不要忘记返回您的承诺:)

option 3 : you can use the statement "await" for your promise but THEN you have to use the keyword async on your "it" function选项 3:您可以使用语句“await”作为您的承诺,但是您必须在“it”函数上使用关键字 async

So in your case you can either put an await on your promise to wait for it to end, or just return your promise.因此,在您的情况下,您可以在承诺上等待等待它结束,或者只是返回您的承诺。 I hope this helps.我希望这有帮助。

Cheers :)干杯:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM