Jest react测试:延迟后检查状态

IT技术 javascript reactjs unit-testing jestjs
2021-05-14 02:40:40

我真的很困惑试图在 Jest 文档https://facebook.github.io/jest/docs/timer-mocks.html#content的帮助下创建测试

在我手动设置状态中的值(使用 setTimeout())后,我试图在容器安装时检查状态,然后在几秒钟后检查状态。

我在 Main 的 componentDidMount 中有一个函数,如下所示:

componentDidMount() {
    this.setStateAfterDelay();
}

该函数的作用是:

setStateAfterDelay = () => {
    setTimeout(() => {
        this.setState({ fruits: ['banana', 'apple', 'orange', 'vodka', 'kiwi'] });
    }, 1500);
}

我通过以下方式实现了第一部分:

const component = mount(<Main />);
expect(component.state().fruits).toEqual(null);

但是我不知道如何在之后再次检查状态,比如说 2000 毫秒?

任何帮助表示赞赏:)

4个回答

虽然 jest 可以轻松运行异步代码,但您可以使用 promise 和 setTimeout 组合稍等片刻。例如,此代码将等待 2 秒:

await new Promise((r) => setTimeout(r, 2000));

全样测试。不要忘记async在回调函数之前添加标志:

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});

另外,请记住,默认的“超时”为 5 秒(5000 毫秒)。如果您的测试可能运行更长时间,您可以jest.setTimeout(30000);test(). 30000 将确保 30 秒内不会超时。您可以添加任何您需要的号码。setTimeout 的完整示例:

jest.setTimeout(30000);

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});

我还没有真正测试过这段代码。但是,我认为类似的东西应该可以工作。

const fruits = ['banana', 'apple', 'orange', 'vodka', 'kiwi'];

it('mock setTimeout test', () => {
 jest.useFakeTimers();
 setTimeout(() => {
   expect(component.state().fruits).toEqual(fruits);
 }, 1500);
 jest.runAllTimers();
});

您不需要延迟测试,只需jest.runAllTimers()在断言之前调用即可

const fruits = ['banana', 'apple', 'orange', 'vodka', 'kiwi'];

it('initializes the fruits state', () => {
 jest.useFakeTimers();
 jest.runAllTimers();
 expect(component.state().fruits).toEqual(fruits);
});

如果您要多次测试,也可以调用useFakeTimers()a beforeEach,也runAllTimers()可以在另一个内部,beforeEach这样您就不会重复自己。

我知道这是关于如何在 20 秒后检查某些内容的问题。但这也可能表明您不想测试 20 秒,因为有时重要的是是否使用正确的输入执行了某些操作。在这种情况下,您可以稍微重组您的代码,以便您可以传入调度函数。例如

    function abc() {
        return dispatch => {
            return Promise.then(res => {})  // this would take 20 seconds
        }
    }

由于dispatch是传入的,因此您可以轻松地在测试代码中使用以下内容。

    const dispatch = Jest.fn()
    abc(dispatch)
    expect(dispatch).toBeCalled()

当然,假设是您不关心是否为 20 秒,而是更关心工作流程。