I'm trying to test components built with Angular Material, however I'm encountering a problem initializing Material elements using Harness Loader as per documentation (section 'Getting started'.). I'd like to extract the logic of initializing them outside of the test methods to make them more concise, but it doesn't seem to work.
Within describe():
let usernameFormField: MatFormFieldHarness;
let registrationButton: MatButtonHarness;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MaterialModule, BrowserAnimationsModule, ReactiveFormsModule],
declarations: [RegistrationComponent],
providers: [ /*provide spies */ ]
}).compileComponents().then(async () => {
fixture = TestBed.createComponent(RegistrationComponent);
loader = TestbedHarnessEnvironment.loader(fixture);
// what works, but I don't like
/*loader.getHarness(
MatFormFieldHarness.with({selector: '#username-form-field'})
).then(harness => {
usernameFormField = harness;
});*/
// what doesn't work
usernameFormField = await loader
.getHarness(MatFormFieldHarness.with({selector: '#username-form-field'}))
// other form elements
// to my confusion, this works without any problem
registrationButton = await loader.getHarness(MatButtonHarness);
});
}));
The await on loader.getHarness() causes lots of errors, seemingly about code not running in 'ProxyZone'.
context.js:265 Unhandled Promise rejection: Expected to be running in 'ProxyZone', but it was not found. ; Zone: <root> ; Task: Promise.then ; Value: Error: Expected to be running in 'ProxyZone', but it was not found.
at Function.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.assertPresent (zone-testing.js:210) [<root>]
at Function.setup (testbed.js:61) [<root>]
at new TestbedHarnessEnvironment (testbed.js:572) [<root>]
at TestbedHarnessEnvironment.createEnvironment (testbed.js:633) [<root>]
at TestbedHarnessEnvironment.createComponentHarness (testing.js:341) [<root>]
at TestbedHarnessEnvironment.<anonymous> (testing.js:384) [<root>]
at Generator.next (<anonymous>) [<root>]
at :9876/_karma_webpack_/node_modules/tslib/tslib.es6.js:74:1 [<root>]
at new ZoneAwarePromise (zone-evergreen.js:960) [<root>]
at __awaiter (tslib.es6.js:70) [<root>]
at TestbedHarnessEnvironment._getQueryResultForElement (testing.js:379) [<root>]
at :9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing.js:366:1 [<root>]
at Array.map (<anonymous>) [<root>]
at TestbedHarnessEnvironment.<anonymous> (testing.js:366) [<root>] Error: Expected to be running in 'ProxyZone', but it was not found.
at Function.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.assertPresent (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:210:1) [<root>]
at Function.setup (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing/testbed.js:61:1) [<root>]
at new TestbedHarnessEnvironment (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing/testbed.js:572:1) [<root>]
at TestbedHarnessEnvironment.createEnvironment (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing/testbed.js:633:1) [<root>]
at TestbedHarnessEnvironment.createComponentHarness (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing.js:341:1) [<root>]
at TestbedHarnessEnvironment.<anonymous> (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing.js:384:1) [<root>]
at Generator.next (<anonymous>) [<root>]
at http://localhost:9876/_karma_webpack_/node_modules/tslib/tslib.es6.js:74:1 [<root>]
at new ZoneAwarePromise (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:960:1) [<root>]
at __awaiter (http://localhost:9876/_karma_webpack_/node_modules/tslib/tslib.es6.js:70:1) [<root>]
at TestbedHarnessEnvironment._getQueryResultForElement (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing.js:379:25) [<root>]
at http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing.js:366:1 [<root>]
at Array.map (<anonymous>) [<root>]
at TestbedHarnessEnvironment.<anonymous> (http://localhost:9876/_karma_webpack_/node_modules/@angular/cdk/fesm2015/testing.js:366:1) [<root>]
I'd also tried running this with a global async function (with the following syntax:)
beforeEach(async( async () => {
// magic happening here
}));
I even tried extracting these harnesses into separate functions, to call them as late as possible, but it also didn't work well:
const usernameFormField = () => {
loader.getHarnes(...);
}
// later in code; not the most elegant, but good enough
const usernameField = await usernameFormField();
expect(await usernameField().hasErrors()).toBeFalsy();
As this post discusses, the 'double-async' construct is valid, if a little clumsy. However, it didn't work for me; the only variant that did was beforeEach(async( () => { ... } ));. Is it possible to use async-await inside beforeEach in async zone, or am I stuck with handling everything manually using Promises?
EDIT: a similar problem shows up not only in beforeEach(), but also in test methods themselves, even when I don't preinitialize the harnesses:
it('should display \'log out\' and \'my account\' buttons when user is authenticated',
async () => {
const EXAMPLE_USERNAME = 'username';
spyOnProperty(authenticationService, 'authenticatedUser')
.and.returnValue(EXAMPLE_USERNAME);
expect(fixture.componentInstance.authenticatedUser)
.toEqual(EXAMPLE_USERNAME);
const logOutButton = await loader
.getHarness(MatButtonHarness.with({text: BUTTON_LOG_OUT_TEXT}));
expect(await logOutButton.isDisabled()).toBeFalsy();
// the following line causes a problem
/*const myAccountButton = await loader
.getHarness(MatButtonHarness.with({text: BUTTON_MY_ACCOUNT_TEXT}));
expect(await myAccountButton.isDisabled()).toBeFalsy();
await myAccountButton.click();
expect(routerSpy.navigateByUrl).toHaveBeenCalled();*/
});
When I uncomment only the first commented line, the code breaks and the test doesn't pass. When I include the async zone, the test passes, but the errors persist. I initially thought this is a problem with initializing the component, but now it seems it's more related to HarnessLoader.
Aucun commentaire:
Enregistrer un commentaire