在 Nodejs 中使用 Jasmine 测试 promise 是不是被解决或拒绝
Posted
技术标签:
【中文标题】在 Nodejs 中使用 Jasmine 测试 promise 是不是被解决或拒绝【英文标题】:Test if a promise is resolved or rejected with Jasmine in Nodejs在 Nodejs 中使用 Jasmine 测试 promise 是否被解决或拒绝 【发布时间】:2015-01-25 16:21:08 【问题描述】:我知道如何在 Mocha 中做到这一点,但想知道如何在 Jasmine 中做到这一点。 我试过这个
describe('test promise with jasmine', function()
it('expects a rejected promise', function()
var promise = getRejectedPromise();
// return expect(promise).toBe('rejected');
return expect(promise.inspect().state).toBe('rejected');
);
);
但是,状态始终为pending
,当然,测试失败。我在网上找不到任何可以让它工作的例子。
有人可以帮我解决这个问题吗?
谢谢。
【问题讨论】:
【参考方案1】:您现在可以使用expectAsync()
期待成功:
it('expect result', async () =>
...
await expectAsync(someAsyncFunction(goodInput)).toBeResolved(expectedResponse)
)
预期失败:
it('expect result', async () =>
...
await expectAsync(someAsyncFunction(badInput)).toBeRejectedWith(expectedResponse)
)
【讨论】:
附加说明:始终使用await
(await expectAsync(...)
)是关键 - 否则测试将始终成功,无论是否承诺是否被拒绝,无论测试是否期望它被拒绝或解决!
其实不然。它也可以从规范中返回。 return expectAsync(pi).toBeResolvedTo(3.14);
这是最惯用的答案,应该被接受。 (当前接受的答案在给出时很好,但您的解决方案现在客观上更好。)【参考方案2】:
要使用 jasmine 测试异步代码,您应该使用 its async syntax,例如:
describe('test promise with jasmine', function(done)
var promise = getRejectedPromise();
promise.then(function()
// Promise is resolved
done(new Error('Promise should not be resolved'));
, function(reason)
// Promise is rejected
// You could check rejection reason if you want to
done(); // Success
);
);
【讨论】:
太棒了!如果你想检查被拒绝的错误内容怎么办?出于某种原因,我不断收到Error: Actual is not a function
或Expected _subscribers : [ ], _state : 0, _detail : to throw error of type Function.
谢谢!
太棒了!是的,这就是我正在做的事情......但如果我这样做 expect(reason).toEqual('someerrorstring');
我会得到我提到的错误......
@Cmag 我建议首先手动检查拒绝原因,以确保它确实是您所期望的。只需使用console.log
或类似的东西。
@Cmag 我建议检查它是否是 Error
类的实例,并且它包含带有预期错误消息的 msg
属性。
从 jasmine ^2.3 开始,我无法将参数传递给 done 函数。最好使用done.fail(new Error('error message'))
。 Reference to documentation【参考方案3】:
jasmine 2.7 及以后版本支持返回承诺,并将对其完成状态进行测试。
测试拒绝:
it('test promise with jasmine', async () =>
try
await getRejectedPromise();
catch (err)
return;
throw new Error('Promise should not be resolved');
);
还是:
it('test promise with jasmine', async () =>
await getRejectedPromise()
.then(
() => Promise.reject(new Error('Promise should not be resolved')),
() => );
);
要验证实际消息,除了通常的instanceof/toBe()
,请放在catch
内:
expect(() => throw err ).toThrow(new MyCustomError('Custom error message'));
这种方法的好处是在测试输出上有更好的失败消息。
预期函数会抛出 MyCustomError:自定义错误消息,但它抛出了另一个错误消息。
比通常的输出要好一些。
测试已解决(再简单不过了):
it('test promise with jasmine', async () =>
await getRejectedPromise();
);
【讨论】:
try/catch 是几乎所有编程语言中最丑陋的编码结构,imo @AlexanderMills 我知道你在开玩笑,但我很久以前就从简单的 promises/then 切换到 async/await。 Ofc 我在有意义的时候使用“旧方式”。 如果你在getRejectedPromise()
上面添加一个promise,这段代码会吞下错误,因为在错误处理程序中没有检查发生什么类型的错误。
因此这段代码并不是真正用于一般用途,它是“漂亮”的简写。【参考方案4】:
您可以使用finally
块来测试承诺状态:
it('should resolve if auth succeed', (done)=>
var p = server.login('user', 'password');
p.finally(()=>
expect(p.isFulfilled()).toBeTruthy();
done();
);
);
您可以使用isFulfilled
检查承诺是否已履行,并使用value
方法检查履行值。对应的拒绝方法为isRejected
和reason
。
【讨论】:
使用这个方法,如何检查promise是否被拒绝,以及查看reject消息? @RuiMarques 你可以使用isRejected
和reason
方法。我更新了我的答案。
finally()
、isFulfilled()
不是标准的(截至 2017 年)。请编辑您的答案以指定外部要求。
这个答案在几个方面是错误的:(1)isFulfilled()
不是根据 ECMAScript 标准的Promise
的官方方法。 (2) 即使是这样,它总是会在finally
中返回true
,因为fulfilled
表示承诺要么被rejected 要么resolved,这总是当finally
被调用时为真。【参考方案5】:
@Leonid 的回答是正确的,但你可以像这样简化,并且只使用 Promise:
it('test promise with jasmine', function()
return getRejectedPromise().then(function()
// Promise should not be resolved, so we reject it
return Promise.reject(new Error('Promise should not be resolved'));
)
.catch(function(err)
if(!/Promise should not be resolved/.test(err && err.message))
return Promise.reject(err);
)
)
【讨论】:
同意。由于丑陋的 catch 条款,我撤回了我的支持。其他人投了反对票,可能是因为缺少此注释并认为它不起作用。 catch 子句是它正常工作所必需的,它是 Promises 的普通 API,我不认为它难看......你会为了让它更漂亮而错误地编码吗?哈哈 test() 是针对上面几行抛出的错误,它是丑陋和懒惰的编码。看我的回答。 @AndréWerlang 嗯,有时您需要测试错误消息,有时需要使用 catch 块,在这种情况下可能不是,但我认为我的更通用,如果您需要添加更多承诺这条链子在路上。以上是关于在 Nodejs 中使用 Jasmine 测试 promise 是不是被解决或拒绝的主要内容,如果未能解决你的问题,请参考以下文章