能否在describe内部使用async + await?

3

我正在尝试运行类似这样的东西

describe('REGISTRATION', async () => {
    const response = await axios.post(url, params);
});

我有一段代码,它的工作方式如下所示:
describe('REGISTRATION', () => {
    // success registration, check expected fields
    test('SUCCESS', async () => {
        const response = await axios.post(url, params);

        const { status, statusText } = response;
        expect(status).toBe(200);
        expect(statusText).toBe('OK');

        const { jwt, user } = response.data;
        expect(typeof(jwt)).toBe('string');

        expect(user).toEqual({
            id: expect.any(Number),
            username: expect.any(String),
            email: expect.stringMatching(emailRegExp),
        });
    });
});

这个可以工作,但是当出现错误时我没有得到错误的详细信息。 我会得到类似于:

expect(received).toEqual(expected) // deep equality
expect(user).toEqual({.......

我想使用async来描述,是因为我想做类似于以下的操作:

describe('REGISTRATION', async () => {
    const response = await axios.post(url, params);

    const { status, statusText } = response;
    const { jwt, user } = response.data;

    test('id', () => {
        expect(Number.isInteger(user.id)).toBe(true);
    });

    test('username', () => {
        expect(typeof(user.username)).toBe('string');
    });

    test('email', () => {
        expect(user.email).toEqual(expect.stringMatching(emailRegExp));
    });
});

我希望在测试时能够详细了解每个错误,有没有人知道如何实现这一点,或者我想得太多了,还有其他的方法吗?


不,但你可以在beforeEach中实现它。 - undefined
你想在哪里处理错误?是在describe内部还是外部?我不是指验证。 - undefined
@fubar 我有点困惑,你这是什么意思? - undefined
我所指的是,在 Promise 回调函数中出现未处理的异常将导致 Promise 被拒绝。这意味着如果某个东西返回一个 Promise,并且你抛出了一个错误,你可以用 try{ let x = await somethingAsync() } catch(err){ ... } 来捕获它。这样一来,你就有不同层次处理错误的选项。另一种捕获错误的方式是:somethingAsync().catch(err => { .... }) - undefined
@fubar 我现在明白你的意思了,但那种方法也不行,或者你能否写下一个带有完整代码示例或者一个fiddle的答案呢?用这种方式进行try catch仍然会显示相同的完整receive, expected而不是逐个显示。 - undefined
2个回答

0

你不需要同时使用asyncdone。Mocha原生支持Promises,所以你可以直接从it回调函数中返回一个Promise。带有async标记的函数总是返回一个Promise - undefined
这难道不是我说的我的工作代码看起来像什么吗?如果有错误,它不会详细显示每个错误。 - undefined

0
所以这里我有一个可以正常运行的示例,我认为至少回答了你关于如何查看异步调用详细信息的问题。
首先是 jesting.js 文件,你可以看到我只返回 Promises。
const jesting = (()=>{
    function sum(a, b){
        return new Promise( (resolve)=>{
            setTimeout(()=>{
                resolve(a+b)
            },2000)
        })
    }

    function sub(a, b){
        return new Promise( (resolve,reject)=>{
            setTimeout(()=>{
                resolve(a-b)
            },2000)
        })
    }

    return {
        sum: sum,
        sub: sub
    }

})();

module.exports = jesting;

现在 jesting.test.js
const jesting = require('./jesting.js');

describe("STUFF", () => {

    const standByMe = jesting.sum(3, 3)

    test('a plus b is x', async () => {
        expect(await standByMe).toBe(6);
    })

    test('a plus b is x', async () => {
        expect(await standByMe).toBe(7);
    })

    test('a minus b is x', async () => {
        expect(await jesting.sub(7, 2).then(res => { return res - 2 })).toBe(3);
    })
})

现在发生了什么?

因此,描述将在开始时执行,并且 standByMe 将被设置为一个包含 Promise 的值,在 2 秒后解析为 6。同时,sub() 将返回一个 Promise,在 2 秒后解析为 5,但我们想要 3 所以我们作弊 :P

请注意,a+b 测试都会 await 相同的 Promise,这在您的情况下只是一个 Promise。正如您所见,使用 sub 时,您还可以在接收到结果之后对其进行操作。另一种有效的方法是 const standByMe = jesting.sum(3, 3).then(res=>{return res+1}),这将返回测试成功的值 7。

结果

Results

哦,而且在回调函数describe上不支持async,所以回答你的主要问题是 => 不支持,但在测试中是可以的

enter image description here


非常感谢你的答案和演示。我知道你的意思,但是如果我使用API调用,那么我必须在每个“test”中调用API,这是我不想要的。我发现有一种叫做“mocks”的东西,可以用来模拟API调用,但我还在努力弄清楚如何做到这一点 :( - undefined
不,你只需要使用const apiCall = axios.post(url, params)一次调用API,然后可以多次等待同一个Promise而无需进行新的调用。也就是所谓的延迟Promise。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接