使用 SinonJS 捕获抛出的错误,UnhandledPromiseRejectionWarning

Catching thrown errors with SinonJS, UnhandledPromiseRejectionWarning

我有以下异步函数来检查承诺的返回值,但我在编写时遇到了问题

    async function fetchData(pageLocation) {
       const data = await 
       apiService.fetchPage(pageLocation);
       if (!data || !data.mapping) {
          const error = new Error(`Unknown channel ${pageLocation}`);
          error.code = 404;
          throw (error);
       }
       return data.mapping;
     }

测试用例

describe.only('fetchData', () => {
    let fetchPage;
    beforeEach(() => {
        fetchPage = 
           sinon.stub().returns(Promise.resolve(mockMapping));
        csfPageService.__set__({
            apiService: {
                fetchPage,
            },
        });
    });

it('should throw an error when there is no available Data', () => {
   channeData', async function() {
        const fetchChannelSectionData = pageService.__get__('fetchData');
        expect(async () => { await fetchData('pageLocation'); }).to.throw();
        expect(fetchPage).to.be.calledWith('pageLocation');
        console.log('----------------------2');
    });

导致主要问题的原因是有一个异步函数和一个承诺,当它不是一个异步函数并且没有等待时我可以使用相同的方法我已经查看了以下链接

但我还没有成功 请告知应该如何完成...

这是我不喜欢 async、await 的原因之一,它们只是 promises 的语法糖,但它们使用 normal/sync 语义,但只是在外观上。 异步函数永远不会抛出异常,无论你在其中抛出的错误有多严重,它们都只会 return 一个被拒绝的承诺。在你的情况下,你的函数根本没有抛出,它是 returning 一个被拒绝的承诺,并且你没有将任何 catch 处理程序附加到该承诺,因此警告。当您使用异步函数或承诺时,忘记正常的错误处理,承诺会自动捕获任何错误并将它们封装在被拒绝的承诺中。

因此,在您的情况下,执行此操作的正确方法会因您的测试框架而异,但可能是这样的:

it('should throw an error when there is no available Data', () => {
   channeData', async function() {
        const fetchChannelSectionData = pageService.__get__('fetchData');
        fetchData('pageLocation').catch(err => {
            expect(err).to.be.an.error();
            expect(fetchPage).to.be.calledWith('pageLocation');
            console.log('----------------------2');
        })
    });