繁体   English   中英

开玩笑 - 等待子 function 在测试期间在主 function 内完成

[英]Jest - await for child function to finish within main function during test

我已经做了一些搜索,但还没有找到解决我当前困境的答案。 我有一个 function ( addMultipleBooks ),它循环通过一个数组并在该循环内,有一个异步 setTimeout function 等待另一个 ZC1C425268E68385D14AB5074C17A ( addNewBook )。

我一直在尝试为主/父 function 编写一个单元测试,以检查子 function 是否被调用,但是测试失败说明

Expected number of calls: >= 1
Received number of calls:    0

不久之后还有一条附加消息

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "message:  undefined".

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "percentage:  100".

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "message:  undefined".

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "percentage:  100".

如何确保在我的测试中等待子 function? 我需要重写父 function 吗? 我尝试使用jest.useFakeTimers()但无济于事。 有什么建议么?

提前致谢

//--------- PARENT.TEST.TS ---------

    it('should call addNewBook for each book parsed from results file', async () => {
        jest.useFakeTimers();
        addMultipleBooks(DUMMY_USER_ID);
        jest.runAllTimers();
        expect(addNewBookSpy).toHaveBeenCalled();
    });

//--------- PARENT.TS ---------

function addMultipleBooks(userID: string) {
    const data = fs.readFileSync('./results.json');
    try {
        const booksArray: formattedBook[] = JSON.parse(data.toString());
        booksArray.map((book, index: number) => {
            setTimeout(async () => {
                const message = await addNewBook(book, userID);
                console.log('message: ', message);
                const percentage = Math.floor(((index + 1) / booksArray.length) * 100);
                console.log('percentage: ', percentage);
            }, (index + 1) * 1000);
        });
    } catch (error) {
        console.log('error parsing book: ', error);
    }
}

您需要等待您正在执行的操作。

目前,检查发生在操作完成之前,然后开玩笑地注意到之后仍在运行的东西并抱怨。

如果你想发起一些异步行为(它还不是面向 Promise - 比如你的基于回调 API 的 setTimeout),那么你需要了解如何使用新的 Promise 创建 Promise。

一旦你有了一系列的承诺,你就可以等待 Promise.all(arrayOfPromises)。 只有在一切都完成后才会出现等待之后的行

我在https://tsplay.dev/N5Pydw上整理了一个演示,填补了您的代码中的一些空白,如下所示。 当您在操场上运行它时,您可以看到事情以正确的顺序发生。

async function addNewBook(options:{book:string, userId:string}){
  const {book, userId} = options;
  console.log(book, userId)
}

async function addMultipleBooks(books:ReadonlyArray<string>, userId: string) {
    try {
        await Promise.all(books.map(async (book, index: number) => {
          await new Promise((resolve) => setTimeout(resolve, (index + 1) * 1000));
          const message = await addNewBook({book, userId});
          console.log('message: ', message);
          const percentage = Math.floor(((index + 1) / books.length) * 100);
          console.log('percentage: ', percentage);
        }))
    } catch (error) {
        console.log('error parsing book: ', error);
    }
}

async function test(){
  const testBooks = ["book1", "book2"] as const;
  const testUserId = "spiderman";
  await addMultipleBooks(testBooks, testUserId)
  console.log("Assertions here")
}

test()

暂无
暂无

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

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