Jasmine:期望在异步函数中抛出错误
Posted
技术标签:
【中文标题】Jasmine:期望在异步函数中抛出错误【英文标题】:Jasmine: Expecting Error to be Thrown in a Async Function 【发布时间】:2017-12-06 04:12:48 【问题描述】:我的 angular2 应用程序中有一个异步函数,我想为其编写单元测试。想象一下我的功能是这样的:
myFunc(a: int): Promise<void>
if (a == 1)
throw new Error('a should not be 1');
let body =
value: a
;
return apiService.patch('/url/', JSON.stringify(body)).toPromise();
现在,我正在考虑检查 if 条件。我尝试了以下代码;但是,这个测试总是失败,因为我的代码实际上并不等待任何结果:
it('should throw error if a = 1', () =>
expect(() =>
mySerivce.myFunc(1);
).toThrow(new Error('a should not be 1'));
)
我不知道应该如何为这些类型的逻辑编写单元测试...
【问题讨论】:
你不应该将 1 传递给你的函数吗? myService.myFunc(1); @ppham27 哎呀!刚刚添加。抓得好! 【参考方案1】:您可以使用 spy 断言方法是否抛出错误:
import Spy = jasmine.Spy;
it('should...', () =>
(mySerivce.myFunc as Spy).and.Callthrough();
mySerivce.myFunc(1);
expect(mySerivce.myFunc).toThrow();
);
可选择使用fakeASync
来解决“racecondition”问题。
希望对你有帮助。
【讨论】:
我假设您的意思是写“它”而不是第一个“除外”。不过,您的方法似乎无法解决我的问题。当函数完全运行时调用 myService.myFunc().then。就我而言,它将引发异常。因此,它永远不会进入 then 块,因为“在默认 jasmine 超时内未调用异步回调函数”或类似的东西。 您在哪里调用了 myFunc(1)? 我认为这是暗示的。我的坏:)【参考方案2】:你可以使用try catch。
这是我想出的,也是 Github 茉莉花问题跟踪器上建议的。
https://github.com/jasmine/jasmine/issues/1410
function double(a: number): Promise<number>
if (a === 1)
throw new Error('a should not be 1')
return new Promise(function (resolve, reject)
setTimeout(resolve, 100, a * 2 )
)
describe('test double', () =>
it('should double any number but 1', async() =>
const result = await double(2);
expect(result).toBe(4)
);
it('should throw an error', async() =>
let error;
try
await double(1)
catch (e)
error = e;
const expectedError = new Error('a should not be 1');
expect(error).toEqual(expectedError)
)
);
我也给自己写了个小帮手
async function unpackErrorForAsyncFunction(functionToTest: Function, ...otherArgs: any[]): Promise<Error>
let error;
try
const result = await functionToTest(...otherArgs);
catch (e)
error = e;
return error;
function double(a: number): Promise<number>
if (a === 1)
throw new Error('a should not be 1')
return new Promise(function (resolve, reject)
setTimeout(resolve, 100, a * 2 )
)
function times(a: number, b: number): Promise<number>
if (a === 1 && b === 2)
throw new Error('a should not be 1 and 2')
return new Promise(function (resolve, reject)
setTimeout(resolve, 100, a * b )
)
describe('test times and double with helper', () =>
it('double should throw an error with test helper', async() =>
const result = await unpackErrorForAsyncFunction(double, 1);
const expectedError = new Error('a should not be 1');
expect(result).toEqual(expectedError)
);
it('times should throw an error with test helper', async() =>
const result = await unpackErrorForAsyncFunction(times, 1, 2);
const expectedError = new Error('a should not be 1 and 2');
expect(result).toEqual(expectedError)
);
);
【讨论】:
【参考方案3】:现在 jasmine (3.3+) 原生支持此功能:
https://jasmine.github.io/api/3.4/async-matchers.html
it('should...', async () =>
await expectAsync(myService.myFunc(1))
.toBeRejectedWith(new Error('a should not be 1'));
);
【讨论】:
我认为这是最好的方法。它对我很有效,而且非常清晰! 我喜欢这个答案,但是它似乎对我不起作用。我正在测试一个返回新承诺的函数。在 promise 内部是它在解决或拒绝命中之前抛出错误的地方。有任何想法吗?错误会出现'Type Error ../filenameHere.ts' 这应该是答案!以上是关于Jasmine:期望在异步函数中抛出错误的主要内容,如果未能解决你的问题,请参考以下文章
afterAll ReferenceError 中抛出错误:未定义模块,nodejs 中的 Karma/Jasmine 测试错误