Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 There is no directive with "exportAs" set to "ngModel" Karma / Jasmine

I'm working on an application which runs fine but the Jasmine tests throw template errors. Since running the application works, the template reference variable can be bound to ngModel, but why doesn't it work when running the tests ? I'm using "@angular/forms": "~2.2.3",

ERROR: 'Unhandled Promise rejection:', 'Template parse errors:
There is no directive with "exportAs" set to "ngModel" ("d="name" required pattern="^[a-zA-Z]+[\s\S]*" 
                [(ngModel)]="model.name" name="name" [ERROR ->]#name="ngModel" >                                    
              </div>                                                                                                
              <div [hidden]="name.valid || name.pristine"  

My app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { LinearProgressIndicatorComponent } from './linear-progress-indicator/linear-progress-indicator.component';
import { MyNewDirectiveDirective } from './directives/my-new-directive.directive';
import { MyNewServiceDirective } from './services/my-new-service.directive';
import { HeaderComponent } from './components/header/header.component';
import { MenuComponent } from './components/menu/menu.component';
import { WatchpanelComponent } from './components/watchpanel/watchpanel.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { InputComponent } from './components/input/input.component';
import { LocalStorage } from './services/local-storage.service';
import { MaterialModule } from '@angular/material';

@NgModule({
  declarations: [
    AppComponent,
    LinearProgressIndicatorComponent,
    MyNewDirectiveDirective,
    MyNewServiceDirective,
    HeaderComponent,
    MenuComponent,
    WatchpanelComponent,
    InputComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    NgbModule.forRoot(),
    MaterialModule.forRoot(),
  ],
  exports: [ MaterialModule ],
  providers: [LocalStorage],
  bootstrap: [AppComponent]
})
export class AppModule { }

input.component.spec.ts:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';

import { InputComponent } from './input.component';

describe('InputComponent', () => {
  let component: InputComponent;
  let fixture: ComponentFixture<InputComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ InputComponent ]
    })
    .compileComponents();

    fixture = TestBed.createComponent(InputComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
like image 518
jsaddwater Avatar asked Dec 17 '16 11:12

jsaddwater


1 Answers

Just like you are doing in the AppModule, you need to import the FormsModule into the TestBed.configureTestingModule. You use this to configure a completely independent module just for the testing

TestBed.configureTestingModule({
  imports: [ FormsModule ],
  declarations: [ InputComponent ]
})

Also another thing.

TestBed.configureTestingModule({
  ...
})
.compileComponents();

fixture = TestBed.createComponent(InputComponent);

You can't do this. .compileComponents resolves asynchronously, and returns a promise. So you can't try to create the components before they have compiled. You need to do

.compileComponents().then(() => {
  fixture = TestBed.createComponent(InputComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
})
like image 137
Paul Samsotha Avatar answered Nov 12 '22 04:11

Paul Samsotha