在我的业力 - 果酱测试之一仍然通过此代码后,我有点担心。
// before each above
comp = fixture.componentInstance
// This spec passes
it(`should not pass because async activity?`, () => {
comp.router.navigate(['home']).then(() => {
expect(true).toBe(true); // should not execute?
// Should only execute if I placed done()?
});
});
当我们使用像async / fakeAsync包装器这样的东西时,我认为.then()没问题
示例代码取自angular docs:
it('should show quote after getQuote promise (async)', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => { // wait for async getQuote
fixture.detectChanges(); // update view with quote
expect(el.textContent).toBe(testQuote);
});
}));
虽然这段代码也没有任何包装器传递:
it(`should also not pass?`, () => {
fixture.whenStable().then(() => {
expect(true).toBe(true); // But it passes!! : /
});
});
所以这让我相信async / fakeAsync包装器可能只是用于拦截我们正在测试的组件/类中的异步活动,并且对我们正在测试的规范没有做任何事情。
任何人都可以验证为什么.then异步代码在没有done()函数的情况下对jasmine规范执行?为什么我们可以这样做,并且在没有添加done()函数的情况下它是否真的安全?
感谢下面的评论:
我做了一个期望(假).toBe(true)和
// This spec fails showing that the then in router executes
it(`should not pass because async activity?`, () => {
comp.router.navigate(['home']).then(() => {
expect(true).toBe(true); // should not execute?
// Should only execute if I placed done()?
});
});
// The then is skipped and spec passes (This should be expected ^^)
it(`then here is skipped without async wrapper`, () => {
fixture.whenStable().then(() => {
expect(false).toBe(true); // But it passes!! : /
});
});
所以我很高兴看到.whenStable()在没有包装器的情况下跳过了那个。还是有点关注router.then()
答案 0 :(得分:0)
async是一个包装器,用于标记调用该函数的人,警告他们该函数包含异步代码。我担心我无法解释你的测试中异步的差异,但我想我可以解释你对完成功能的困惑。
首先让我清理其他东西,你的第一次和第三次测试总是会通过。请记住,空测试通过:
it(`passes`, () => {
});
因此,如果你添加一个期望应该通过的if语句,那么测试将传递if语句是否为真。
it(`still passes`, () => {
if (21 < 42) {
expect(true).toBe(true);
}
});
如果要使用带有茉莉花测试的done函数,则需要将其作为参数传递给测试。以下是几个例子:
it(`passes because done in wrong place`, (done) => {
setTimeout(() => {
expect(false).toBe(true);
}, 500);
done();
});
it(`correctly does not pass as expect trigered`, (done) => {
setTimeout(() => {
expect(false).toBe(true);
done();
}, 500);
});
请记住,除非您更改jasmine.DEFAULT_TIMEOUT_INTERVAL,否则Jasmine将在5秒后超时任何测试。
您希望使用done函数让Jasmine知道您的测试已完成。我不确定它是否真的需要,但我想可能有一个论点,它可以使用稍微更具可读性的回调函数进行测试。
答案 1 :(得分:0)
async
和fakeAsync
依赖于区域,他们会等待属于规范的区域中评估的异步代码。如果在组件内部或内部规范函数中创建了承诺,只要它保留在区域内就没有关系。
此
it(`passes with Zone.js`, () => {
Promise.resolve().then(() => {
expect(true).toBe(true);
});
});
有效,因为Jasmine已修补以使用Zone.js并支持async
/ fakeAsync
帮助程序,并导致与原始行为不兼容的行为。当履行承诺与then
链接时,即使没有async
,也可能会检测到期望并且规范订单将被保留,但不应依赖此行为。
此
it(`fails with Zone.js`, () => {
new Promise(resolve => setTimeout(resolve)).then(() => {
expect(true).toBe(true);
});
});
将在Zone.js中失败。
如果没有修补Jasmine,这两个例子都无法发现期望。
一个好的做法是始终从异步规范返回一个promise(Jasmine 2.7及更高版本支持不带async
/ fakeAsync
助手的promise返回:
it(`should not pass because async activity?`, async () => {
await comp.router.navigate(['home']);
expect(true).toBe(true);
});