create method
Creates a new test application with T
as the root component.
If beforeChangeDetection
is set, it is called before any initial
change detection (so you can do initialization of component state that
might be required).
Returns a future that completes with a fixture around the component.
Implementation
Future<NgTestFixture<T>> create({
FutureOr<void> Function(Injector)? beforeComponentCreated,
FutureOr<void> Function(T instance)? beforeChangeDetection,
}) {
// We *purposefully* do not use async/await here - that always adds an
// additional micro-task - we want this to fail fast without entering an
// asynchronous event if another test is running.
_checkForActiveTest();
// Future.sync promotes synchronous errors to Future.error if they occur.
return Future<NgTestFixture<T>>.sync(() {
// Ensure that no tests have started since the last microtask.
_checkForActiveTest();
// Create a zone to intercept timer creation.
final timerHookZone = TimerHookZone();
late final NgZone ngZoneInstance;
NgZone ngZoneFactory() {
return timerHookZone.run(() {
return ngZoneInstance = NgZone();
});
}
// Created within "createStabilizersAndRunUserHook".
late final NgTestStabilizer allStabilizers;
Future<void> createStabilizersAndRunUserHook(Injector injector) async {
// Some internal stabilizers get access to the TimerHookZone.
// Most (i.e. user-land) stabilizers do not.
final createStabilizer = _createStabilizer;
allStabilizers = createStabilizer is AllowTimerHookZoneAccess
? createStabilizer(injector, timerHookZone)
: createStabilizer(injector);
// If there is no user hook, we are done.
if (beforeComponentCreated == null) {
return;
}
// If there is a user hook, execute it within the ngZone:
final completer = Completer<void>();
ngZoneInstance.runGuarded(() async {
try {
await beforeComponentCreated(injector);
completer.complete();
} catch (e, s) {
completer.completeError(e, s);
}
});
return completer.future.whenComplete(() => allStabilizers.update());
}
return bootstrapForTest<T>(
_componentFactory,
_host ?? _defaultHost(),
_rootInjector,
beforeComponentCreated: createStabilizersAndRunUserHook,
beforeChangeDetection: beforeChangeDetection,
createNgZone: ngZoneFactory,
).then((componentRef) async {
_checkForActiveTest();
await allStabilizers.stabilize();
final testFixture = NgTestFixture(
componentRef.injector.provideType(ApplicationRef),
componentRef,
allStabilizers,
);
// We need the local variable to capture the generic type T.
activeTest = testFixture;
return testFixture;
});
});
}