diff --git a/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts b/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts index eacb67eb82..bf5e5202c8 100644 --- a/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts +++ b/aio/content/examples/testing/src/app/shared/canvas.component.spec.ts @@ -1,6 +1,21 @@ +// #docplaster +// #docregion without-toBlob-macrotask import { TestBed, async, tick, fakeAsync } from '@angular/core/testing'; import { CanvasComponent } from './canvas.component'; + describe('CanvasComponent', () => { + // #enddocregion without-toBlob-macrotask + // #docregion enable-toBlob-macrotask + beforeEach(() => { + window['__zone_symbol__FakeAsyncTestMacroTask'] = [ + { + source: 'HTMLCanvasElement.toBlob', + callbackArgs: [{ size: 200 }], + }, + ]; + }); + // #enddocregion enable-toBlob-macrotask + // #docregion without-toBlob-macrotask beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ @@ -8,20 +23,16 @@ describe('CanvasComponent', () => { ], }).compileComponents(); })); - beforeEach(() => { - window['__zone_symbol__FakeAsyncTestMacroTask'] = [ - { - source: 'HTMLCanvasElement.toBlob', - callbackArgs: [{ size: 200 }] - } - ]; - }); + it('should be able to generate blob data from canvas', fakeAsync(() => { const fixture = TestBed.createComponent(CanvasComponent); + const canvasComp = fixture.debugElement.componentInstance; + fixture.detectChanges(); + expect(canvasComp.blobSize).toBe(0); + tick(); - const app = fixture.debugElement.componentInstance; - expect(app.blobSize).toBeGreaterThan(0); + expect(canvasComp.blobSize).toBeGreaterThan(0); })); }); - +// #enddocregion without-toBlob-macrotask diff --git a/aio/content/examples/testing/src/app/shared/canvas.component.ts b/aio/content/examples/testing/src/app/shared/canvas.component.ts index 251ee01d96..fdfd9db8b0 100644 --- a/aio/content/examples/testing/src/app/shared/canvas.component.ts +++ b/aio/content/examples/testing/src/app/shared/canvas.component.ts @@ -1,25 +1,32 @@ +// #docplaster +// #docregion import-canvas-patch +// Import patch to make async `HTMLCanvasElement` methods (such as `.toBlob()`) Zone.js-aware. +// Either import in `polyfills.ts` (if used in more than one places in the app) or in the component +// file using `HTMLCanvasElement` (if it is only used in a single file). +import 'zone.js/dist/zone-patch-canvas'; +// #enddocregion import-canvas-patch +// #docregion main import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'sample-canvas', - template: '' + template: '', }) export class CanvasComponent implements AfterViewInit { - blobSize: number; + blobSize = 0; @ViewChild('sampleCanvas') sampleCanvas: ElementRef; - constructor() { } - ngAfterViewInit() { - const canvas = this.sampleCanvas.nativeElement; + const canvas: HTMLCanvasElement = this.sampleCanvas.nativeElement; const context = canvas.getContext('2d'); - if (context) { - context.clearRect(0, 0, 200, 200); - context.fillStyle = '#FF1122'; - context.fillRect(0, 0, 200, 200); - canvas.toBlob((blob: any) => { - this.blobSize = blob.size; - }); - } + + context.clearRect(0, 0, 200, 200); + context.fillStyle = '#FF1122'; + context.fillRect(0, 0, 200, 200); + + canvas.toBlob(blob => { + this.blobSize = blob.size; + }); } } +// #enddocregion main diff --git a/aio/content/guide/testing.md b/aio/content/guide/testing.md index 0eeb798aed..c3dead9ba1 100644 --- a/aio/content/guide/testing.md +++ b/aio/content/guide/testing.md @@ -899,8 +899,7 @@ In production, change detection kicks in automatically when Angular creates a component or the user enters a keystroke or an asynchronous activity (e.g., AJAX) completes. -The `TestBed.createComponent` does _not_ trigger change detection. -a fact confirmed in the revised test: +The `TestBed.createComponent` does _not_ trigger change detection; a fact confirmed in the revised test: @@ -1051,8 +1050,7 @@ attempt to reach an authentication server. These behaviors can be hard to intercept. It is far easier and safer to create and register a test double in place of the real `UserService`. -This particular test suite supplies a minimal mock of the `UserService` that satisfies the needs of the `WelcomeComponent` -and its tests: +This particular test suite supplies a minimal mock of the `UserService` that satisfies the needs of the `WelcomeComponent` and its tests: + region="without-toBlob-macrotask"> + region="main"> -If you want to support such a case, you need to define the `macroTask` you want to support in `beforeEach()`. +If you want to support such a case, you need to define the macro task you want to support in `beforeEach()`. For example: -```javascript -beforeEach(() => { - window['__zone_symbol__FakeAsyncTestMacroTask'] = [ - { - source: 'HTMLCanvasElement.toBlob', - callbackArgs: [{ size: 200 }] - } - ]; -}); + + + +Note that in order to make the `` element Zone.js-aware in your app, you need to import the `zone-patch-canvas` patch (either in `polyfills.ts` or in the specific file that uses ``): + + + -it('toBlob should be able to run in fakeAsync', fakeAsync(() => { - const canvas: HTMLCanvasElement = document.getElementById('canvas') as HTMLCanvasElement; - let blob = null; - canvas.toBlob(function(b) { - blob = b; - }); - tick(); - expect(blob.size).toBe(200); - }) -); -``` #### Async observables @@ -3635,7 +3627,7 @@ next to their corresponding helper files. #### Keep it simple [Component class testing](#component-class-testing) should be kept very clean and simple. -It should test only a single unit. On a first glance, you should be able to understand +It should test only a single unit. On a first glance, you should be able to understand what the test is testing. If it's doing more, then it doesn't belong here. {@a q-end-to-end}