c语言sscanf函数的用法是什么
288
2022-09-27
Jest重点难点 - 异步代码的测试
Jest的文档有时候晦涩难懂,中文文档又有股浓浓的机翻味,因此将自己的学习笔记整理出来,融入自己的一些理解,力争做到通俗易懂。后面还会整理函数模拟,计时器模拟等内容,希望对大家有所帮助。
回调函数
需在回调函数中调用done函数,Jest会在done函数执行结束后,结束测试。
function fetchData(fn) { setTimeout(() => { fn('Hello world') }, 1000);}test('callback', (done) => { function callback(data) { expect(data).toBe('Hello world') done() // 在回调函数中记得调用done函数,不然测试用例将无法通过,显示超时错误。 } fetchData(callback)})复制代码
如果done() 函数从未被调用,测试用例会显示超时错误!!!
下面修改一下测试用例,将expect(data).toBe('Hello world') 改为 expect(data).toBe('Hello Jest')。
test('callback', (done) => { function callback(data) { expect(data).toBe('Hello Jest') done() } fetchData(callback)})复制代码
显然这是不能通过测试的,但是Jest给我们的提示却是thrown: "Exceeded timeout of 5000 ms for a test……,即超时错误。这是因为expect执行失败后,会抛出一个错误,导致后面的 done() 不再执行,从而显示超时。如果我们想知道测试用例失败的原因,需要将 expect 放入 try 中,然后将 error 传递给 catch 中的 done函数。
因此,完善的测试用例应该如下:
test('callback', done => { function callback(data) { try { expect(data).toBe('Hello Jest') done() } catch (error) { done(error) } } fetchData(callback)});复制代码
Promise
如果异步代码使用了 Promise,需要在测试用例中将Promise对象返回
function fetchData() { return new Promise((resolve) => { setTimeout(() => { resolve('Hello world') }, 1000); })}test('Promise', () => { // 一定记得加上 return,否则测试在 fetchData 执行完成之前就已经结束,随后then中的expect也不会执行,会导致超时错误!!! return fetchData().then(data => { expect(data).toBe('Hello world') })})复制代码
如果需要测试reject状态的Promise,除了需要在catch方法中执行断言外,还需要使用expect.assertions来验证是否调用了指定次数的断言。
比如,我们需要测试接口失败时返回的数据。先修改fetchData函数,通过传入的success参数来模拟接口的成功和失败。
function fetchData(success) { return success ? Promise.resolve('success message') : Promise.reject('error message')}复制代码
如果接口返回失败的情况下,此时以下的测试用例时可以通过的,这没有问题。
test('Promise rejected', () => { return fetchData(false).catch(error => { expect(error).toBe('error message') // 测试通过 })})复制代码
但是如果接口返回成功,其实测试用例也是可以通过的。这是因为接口成功的话,是不会执行catch函数的。那么 catch 里面的断言也就不会被执行,所以能通过测试。看下面的例子:
test('Promise rejected', () => { // 接口成功,因为不会执行catch return fetchData(true).catch(error => { expect(error).toBe('error message') // 测试通过 })})复制代码
可是这并不符合我们的预期啊,我们就是想测试接口失败时的数据,此时,我们可以使用expect.assertions(1),这样就可以知道,至少有一次expect被执行,也就是catch一定会被执行,那么,fetchData一定要是返回失败的,而不是成功的,因此我们要修改测试用例,将fetchData(true)改为fetchData(false),来确保接口是返回是失败的,这样才是严谨的测试用例。
test('Promise rejected', () => { expect.assertions(1) // 至少执行一次 expect // 将fetchData(true)改为fetchData(false),接口失败才能执行catch里面的断言 return fetchData(false).catch(error => { expect(error).toBe('error message') // 测试通过, })})复制代码
当测试 promise 的时候,特别是测试 catch,一定要加 expect.assertions() 确保测试代码会执行
resolves 和 rejects 匹配器
resolves和rejects匹配器可以让我们很方便的测试Promise。当然不要忘记将整个断言作为返回值返回
test('the data is success message', () => { // 不要忘记将整个断言作为返回值返回 return expect(fetchData(true)).resolves.toBe('success message')});test('the fetch fails with an error', () => { // 不要忘记将整个断言作为返回值返回 return expect(fetchData(false)).resolves.toBe('error message')});复制代码
async 和 await
我们也可以在测试中使用async 和 await,写异步测试用例时,可以在传递给test的函数前面加上async。
test('the data is success message', async () => { const data = await fetchData(true) expect(data).toBe('success message')});test('the fetch fails with an error', async () => { expect.assertions(1) try { await fetchData(false) } catch (e) { expect(e).toBe('error message') }});复制代码
你也可以将 async and await和 resolves or rejects一起使用。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~