As of Feb 2019, episodes in the 13.x range on CodeCraft.tv are the best resource, known to me, for learning: How to test components in Angular7.
But even after absorbing all that goodness, I still found it difficult to add tests in an existing project. Most of it had to do with watch ng test fail and then figuring out all the dependencies that were unaccounted for.
Here is a list of gotchas:
- ng testwill fail due to missing dependencies after you create a- specusing tools that generate it for any existing component. Known tools: angular-spec-generator and ngx-spec
- Complaints about ngModels? That comes fromFormsModuleso if the component being tested uses that then you inject it viaimports: [FormsModule]
- If you see complaints about missing HttpClientand/orHttpHandler, instead of configuring theproviders:beforeEach(async () => { TestBed.configureTestingModule({ declarations: [...], imports: [], providers: [ HttpClient, HttpHandler ] }).compileComponents(); });You should configure the imports:beforeEach(async () => { TestBed.configureTestingModule({ declarations: [...], imports: [ HttpClientModule ], providers: [...] }).compileComponents(); });
- Complaints about mdbModal? That comes fromMDBBootstrapModuleso if the component being tested uses that then you inject it viaimports: [MDBBootstrapModule.forRoot()]
- For material-design-bootstrap, if you misconfigure it as imports:[MDBBootstrapModule]then you will see random errors like:Error: StaticInjectorError(DynamicTestModule)[ModalDirective -> ComponentLoaderFactory]: StaticInjectorError(Platform: core)[ModalDirective -> ComponentLoaderFactory]: NullInjectorError: No provider for ComponentLoaderFactory!While the real issues is that it should be initialized with forRoot()beforeEach(async () => { TestBed.configureTestingModule({ declarations: [...], imports: [ //MDBBootstrapModule // NO! NO! MDBBootstrapModule.forRoot() // YES ], providers: [...] }).compileComponents(); });
- Complaints about routerLink?- Don’t use the combination ofimports:[RouterModule]andproviders:[Router]
- Use imports:[RouterTestingModule.withRoutes(routes)]
- You can view CodeCraft episode 13.13 to watch this done the right way.
 
- Don’t use the combination of
- Complaints about zoneorinjector# can't find the zone dependency Failed: Zone is needed for the async() test helper but could not be found. Please make sure that your environment includes zone.js/dist/zone.js # testbed hasn't been initialized Failed: Cannot read property 'injector' of nullUsually all of this is available in src/test.tsand used byng testautomatically … but is you useprotractoras the entrypoint, then you must incorporate workarounds intoe2e/protractor.conf.jsfile’sonPrepare()method somehow.- Relevant Stack Overflow posts
        - https://stackoverflow.com/questions/40699593/cannot-read-property-injector-of-null-jasmine-angular-2#answer-40699740
            - https://github.com/angular/quickstart/blob/master/karma-test-shim.js#L75
 
- https://github.com/angular/quickstart/blob/master/karma-test-shim.js#L75
 
- https://stackoverflow.com/questions/40699593/cannot-read-property-injector-of-null-jasmine-angular-2#answer-40699740
            
 
- Relevant Stack Overflow posts
        
- TBD…
Written with StackEdit.