5

I have written my first angular application in Angular 6.

I have not written any test yet but there are some default test files created automatically while generating components and services.

When I run the auto-generated tests using

ng test

It gives too many errors. One error out of them is like

ChangeAvatarModalComponent should create

Failed: Template parse errors:
There is no directive with "exportAs" set to "ngForm" ("
<div class="modal-body">

  <form [formGroup]="changeAvatarForm" id="avatar-form" [ERROR ->]#formDir="ngForm" (submit)="onSubmit()">
  <div class="row">
    <div class="col-md-12">
"): ng:///DynamicTestModule/ChangeAvatarModalComponent.html@8:56
Can't bind to 'formGroup' since it isn't a known property of 'form'. ("
<div class="modal-body">

I have an account module which have ChangeAvatarModalComponent.

I have following lines inside account.module.ts

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forChild(AccountRoutes),
    NgbModule
  ],
  declarations: [
    ChangeAvatarModalComponent
  ],
  entryComponents: [
    ChangeAvatarModalComponent
  ]
})
export class AccountModule { }

and also FormsModule and ReactiveFormsModule are imported in app.module.ts

There are many such errors in the log generated.

Edit 2: change-avatar-modal.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ChangeAvatarModalComponent } from './change-avatar-modal.component';

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

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

  beforeEach(() => {
    fixture = TestBed.createComponent(ChangeAvatarModalComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
danday74
  • 52,471
  • 49
  • 232
  • 283
Anuj TBE
  • 9,198
  • 27
  • 136
  • 285

1 Answers1

3

You are not showing you .spec.ts file in the code you have given.

The reason you are getting the problems with forms is because in your spec file you need to import the relevant modules too like this:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        TranslateModule.forRoot({
          loader: {provide: TranslateLoader, useClass: TranslateFakeLoader}
        }),
        HttpClientModule,
        HttpClientTestingModule,
        FormsModule,
        SfFormModule,
        ReactiveFormsModule,
        NguiAutoCompleteModule,
        NgxMyDatePickerModule,
        NgxPermissionsModule.forRoot(),
        PipeModule,
        StoreModule.forRoot({}),
        LayoutsModule
      ],
      declarations: [
        ExampleComponent
      ],
      providers: [
        {provide: APP_BASE_HREF, useValue: '/'},
        {provide: ToastrService, MockToastrService},
        ActionsSubject,
        SimService
      ]
    }).compileComponents()
  }))

  beforeEach(() => {
    fixture = TestBed.createComponent(ExampleComponent)
    component = fixture.componentInstance
    fixture.detectChanges()
  })

  it('should create', () => {
    expect(component).toBeTruthy()
  })
})

In your case you need to import FormsModule and/or ReactiveFormsModule in your spec file and prob other stuff too.

To reduce the number of imports you may be able to get away with just importing your own modules into the spec file - e.g. AccountModule and/or AppModule - since these already import the forms stuff.

danday74
  • 52,471
  • 49
  • 232
  • 283
  • 1
    added spec file. Check **Edit 2** – Anuj TBE Oct 10 '18 at 04:47
  • ok cool, as expected you are missing the imports in your spec file - fix that and it should fix your problem :) – danday74 Oct 10 '18 at 04:49
  • Do I need to add all import lines you have added in your answer or just the one I have imported in **account.module.ts**? – Anuj TBE Oct 10 '18 at 04:51
  • Just the imports you need for the specific component you are testing, although importing more than you need does not hurt. You could just import AccountModule since that imports the forms module. You will prob find when you have done that, different errors might appear relating to other missing imports. Just work your way through them one by one and eventually it will stop complaining :) – danday74 Oct 10 '18 at 04:53
  • The answer I gave is just an example of what a spec file looks like, you won't need to import most that stuff. – danday74 Oct 10 '18 at 04:54
  • I imported `AccountModule` which is giving conflicting error as `Error: Type ChangeAvatarModalComponent is part of the declarations of 2 modules: AccountModule and DynamicTestModule! Please consider moving ChangeAvatarModalComponent to a higher module that imports AccountModule and DynamicTestModule. You can also create a new NgModule that exports and includes ChangeAvatarModalComponent then import that NgModule in AccountModule and DynamicTestModule.` – Anuj TBE Oct 10 '18 at 04:56
  • Ok this is because you are declaring ChangeAvatarModalComponent in your spec file and in AccountModule. Just remove ChangeAvatarModalComponent from your spec file declarations array, like this ... declarations: [ ChangeAvatarModalComponent ] ... becomes ... declarations: [] – danday74 Oct 10 '18 at 05:00
  • Thanks. One more query regarding adding `services`. I have **account.service.ts** which is using custom http handler **AppHttpClient**. I have added `providers: [AccountService, HttpClient, HttpHandler]` to **account.service.spec.ts** file. It asking to add `HttpClient` and `HttpHandler` to all component's spec files. Is it the expected behaviour? – Anuj TBE Oct 10 '18 at 05:10
  • Any spec file which uses HTTP directly on indirectly via a service will need HTTP stuff imported. I tend to import HttpClientTestingModule and/or HttpClientModule into the spec file, which seems to get rid of most issues. – danday74 Oct 10 '18 at 05:16
  • You could create a common testing module which imports the modules you need to use in most spec files and just import that instead of copying and pasting everywhere. – danday74 Oct 10 '18 at 05:18