ng test gives Component should create
Asked Answered
P

1

6

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();
  });
});
Plank answered 10/10, 2018 at 4:30 Comment(0)
B
4

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.

Blancmange answered 10/10, 2018 at 4:40 Comment(10)
added spec file. Check Edit 2Plank
ok cool, as expected you are missing the imports in your spec file - fix that and it should fix your problem :)Blancmange
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?Plank
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 :)Blancmange
The answer I gave is just an example of what a spec file looks like, you won't need to import most that stuff.Blancmange
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.Plank
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: []Blancmange
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?Plank
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.Blancmange
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.Blancmange

© 2022 - 2024 — McMap. All rights reserved.