[英]Does fixture.whenStable() actually do anything in my angular tests if not within an async test execution zone?
I have been reading a lot about angular testing lately and the pairs are always async+fixture.whenStable and fakeAsync+tick, however you can always call fixtrue.whenStable as it is not tightly coupled.我最近阅读了很多关于角度测试的文章,这些对总是 async+fixture.whenStable 和 fakeAsync+tick,但是你总是可以调用 fixtrue.whenStable 因为它不是紧密耦合的。 If you call it when not using the async utility to track promises in a test zone will it actually do anything?如果您在不使用 async 实用程序跟踪测试区域中的承诺时调用它,它实际上会做任何事情吗?
For example:例如:
it('should be able to do this thing that needs some async setup', () => {
fixture.detectChanges();
fixture.whenStable().then()
});
I understand the difference between FakeAsync/Tick
and fixture.detectChanges
.我明白之间的差别FakeAsync/Tick
和fixture.detectChanges
。 My question is regarding what fixture.whenstable
will do when inside of a FakeAsync
execution zone as an Async
zone should keep track of async work allowing fixture.whenstable
to hook into that tracking, at least as I understand it.我的问题是关于什么fixture.whenstable
将尽时,内部FakeAsync
执行区域为Async
区应保持异步工作轨道允许fixture.whenstable
据我了解挂接到那个跟踪,至少。 Or indeed if used and not within an async execution zone at all.或者实际上,如果使用并且根本不在异步执行区域内。
So if fixture.whenstable is used inside a FakeAsync function, or a function that does not setup an async execution zone, will it work as intended?因此,如果在 FakeAsync 函数或未设置异步执行区域的函数中使用 fixture.whenstable,它会按预期工作吗?
No the whenStable()
does nothing if you test without async
or fakeAsync
.不,如果您在没有async
或fakeAsync
情况下进行测试,则whenStable()
什么也不fakeAsync
。 What whenStable()
does is to wait for all tasks in the test NgZone
to complete. whenStable()
所做的是等待测试NgZone
中的所有任务完成。 When you don't test with async the NgZone
does not get created at all and whenStable()
just returns immediately.当你不使用测试的异步NgZone
没有得到根本创造whenStable()
只是立即返回。
If you want more detail check the code for ComponentFixture in GitHub .如果您想了解更多详细信息,请查看GitHub 中ComponentFixture 的代码。
The accepted answer may have been correct when it was written, but as of late 2020, when using node_modules/zone.js/bundles/zone-testing.umd.js
, I don't think it is anymore.接受的答案在编写时可能是正确的,但截至 2020 年末,当使用node_modules/zone.js/bundles/zone-testing.umd.js
,我认为不再正确。 I can't find a citation in the docs, but I can confirm experimentally that a test zone is always used, and that whenStable
waits for its tasks to complete.我在文档中找不到引文,但我可以通过实验确认始终使用测试区,并且whenStable
等待其任务完成。
This is very simple to try for yourself.这很简单,可以自己尝试。 Just create an empty test, and add只需创建一个空测试,然后添加
//// In my.component.ts
import { timer } from "rxjs";
import { map } from "rxjs/operators";
@Component({
template: `<p>{{clock|async}}</p>,
...
})
export class MyComponent {
/** @internal */ public readonly clock = timer(0,1000).pipe(map(() => new Date()));
}
//// In `my.component.spec.ts`
beforeEach(async () => {
testBed.configureTestingModule(...);
await testBed.compileComponents();
fixture = testBed.createComponent(MyComponent);
await fixture.whenStable();
});
Because rxjs timer
uses setInterval
under the hood, it's flagged as always having a pending task, so whenStable
never resolves.因为 rxjs timer
在幕后使用setInterval
,它被标记为总是有一个挂起的任务,所以whenStable
永远不会解决。 Jasmine will fail with a timeout, waiting for the Promise returned by the setup method to resolve. Jasmine 会因超时而失败,等待 setup 方法返回的 Promise 解决。 (Ask me how I discovered this...) (问我是怎么发现的……)
try to wrap your test code into waitForAsync尝试将您的测试代码包装到waitForAsync 中
this is new recommended way to test async code in angular这是在 angular 中测试异步代码的新推荐方法
@Component()
export class SomeComponent implements OnInit {
async ngOnInit() {
// to test component with async ngOnInit use waitForAsync
}
}
beforeEach(
waitForAsync(() => {
fixture = TestBed.createComponent(SomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
})
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.