How to reduce boiler and repeatitive code when writing test cases - angular6

I am writing a lot of boiler and duplicate code in each describe section of my app-component.spec.ts. Is there a way to reduce it? Another problem is that whenever I write a new component, I have to explicitly add reference of the new component in each describe. For eg.
describe('AppComponent Test suite', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach((() => {
TestBed.configureTestingModule({
declarations: [
AppComponent,
... //29 components need to be referrred her
],
imports: [
AppRoutingModule,
QuillModule,
BrowserModule,
HttpClientModule,
MatProgressBarModule,
BrowserAnimationsModule,
HttpClientXsrfModule.withOptions({cookieName: 'CJCsrfCookie', headerName: 'CJCsrfHeader'}),
ReactiveFormsModule
],
providers: [{provide: APP_BASE_HREF, useValue: '/'},
...//14 services need to be added here
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
fit('should create the app', (async() => {
expect(component).toBeTruthy();
}));
...
});
If I write another describe, I'll have to write all the imports and declarations again. Can I avoid this?

It seems it is quite easy to do it unless I am mistaken!
I just import the AppModule. For any providers I want to provide an alternate of, I just mention that explicitly.
eg.
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AppModule],
providers: [
{provide: UserManagementService, useClass: MockUserManagementService}, //mock user management service
],
})
.compileComponents();
}));
The above replaces
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [//23 components. These in new implementation come from AppModule
],
imports: [AppModule],
providers: [//14 services. They also some now from AppModule,
{provide: UserManagementService, useClass: MockUserManagementService}, //mock user management service
{provide: APP_BASE_HREF, useValue: '/'}],
})
.compileComponents();
}));

Related

HTML image gets rendered on top of Karma

How come a logo which I have in my navbar component is rendered in Karma when I run "ng test"?
When running "ng test" it appears like in the image below:
The following code is from my app.component.spec.ts file.
describe("AppComponent", () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let de: DebugElement
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
AngularFireDatabaseModule,
AngularFireAuthModule,
AngularFirestoreModule,
AngularFireStorageModule,
AngularFireModule.initializeApp( environment.firebase)],
declarations: [
AppComponent,
NavbarComponent],
providers:
[
DatabaseService,
],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});
I am guessing the image appears without CSS of how big or small it should be.
If NavbarComponent is not important to your unit tests for AppComponent, you can use NO_ERRORS_SCHEMA to make NavbarComponent be a dead HTML element in your unit tests.
Try:
import { NO_ERRORS_SCHEMA } from '#angular/core';
....
declarations: [
AppComponent,
// NavbarComponent,
],
schemas: [NO_ERRORS_SCHEMA],
Then hopefully the image will not appear.

How to nest more than 1 level route in Angular route?

i make an dashboard app for manage data using angular 6. but i stuck when i nest more than 1 lazyload route, it's not work, It's seem like can not add more than 1 lazyload route in angular router
My App routing :
const appRoutes: Routes = [
{
path: '',
component: SigninComponent,
pathMatch: 'full'
},
{
path: 'dashboard',
loadChildren: './core/dashboard/dashboard.module#DashboardModule'
}
];
#NgModule({
imports: [
RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
my dashboard route
const dashboardRoutes: Routes = [
{
path: '',
component: DashboardComponent,
children: [
{
path: 'products',
pathMatch: 'full',
loadChildren: './products/products.module#ProductModule'
},
]
}
];
#NgModule({
imports: [RouterModule.forChild(dashboardRoutes)],
exports: [RouterModule]
})
My product route:
const productRoutes: Routes = [
{
path: '',
component: ProductListComponent,
children: [
{
path: ':id',
component: ProductEditComponent
},
{
path: 'addproduct',
component: ProductCreateComponent
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(productRoutes)],
exports: [RouterModule]
})
when i access localhost:4200/dashboard/products/id3 it take an error: can not match any route 'dashboard/products/id3'. I think i wrong some where in routing setup but i cant not find where is an error. Anyone can help me ?
I've create a page for you..Just check and do the changes accordingly. You need to check module path correctly otherwise it should work with no issue. You can change the url to hello.
https://stackblitz.com/edit/angular-lazy-loading-nweyjt
// For eg.
// https://stackblitz.com/edit/angular-lazy-loading-nweyjt/hello/3

Angular6 entry component on lazy loaded feature module

Is possible declare entry components on lazy loaded feature module ?
I get such an error like this:
ERROR Error: No component factory found for NewMessageModalComponent. Did you add it to #NgModule.entryComponents?
This is my feature module :
#NgModule({
declarations: [
NewMessageModalComponent
],
imports: [
MessagesRoutingModule
],
entryComponents: [
NewMessageModalComponent
]
})
export class MessagesModule {
}
root AppModule
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
root RoutingModule
const routes: Routes = [
{
path: 'messages',
loadChildren: './messages/messages.module#MessagesModule',
}
];
#NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [RouterModule],
providers: []
})
export class AppRoutingModule {
}
I know , this works when I declare entry components on AppModule, but why not working on feature module ?
This seems to be not currently supported and the issue is tagged as a "feature".
https://github.com/angular/angular/issues/14324#issuecomment-433389833
Proposed solution: Even though this goes against the modular design
adopted by Angular itself, I think that the complexity provided to
create dynamic components could be softened by simply appending the
LazyModule's entryComponents to the RootInjector's entryComponents and
to avoid flooding the RootInjector, whenever you navigate out (which
destroys the LazyModule), the previously injected entryComponents
would be erased from the array.

Cannot find a module angular 4

Initially the app displays login page and navigates to maincontent component now i want to navigate from dashboard component to app details component but am getting an error as
Error: Component DashboardComponent is not part of any NgModule or the module has not been imported into your module.
In my app.module.ts i have imported all the components
below is the routes that i have mentioned in app.module.ts
const appRoutes: Routes=[
{ path:'', redirectTo:'/login',pathMatch:'full'},
{ path: 'login', component: LoginComponent},
{ path: 'maincontent', loadChildren:
'./maincontent/maincontent.module#MainContentModule'
}
];
below is the routes mentioned in MainContentModule
export const ROUTES: Routes = [
{
path: 'maincontent',
component: MainContentComponent,
children: [
{ path: 'dashboard', component:DashboardComponent,
loadChildren: './dashboard/dashboard.module#DashboardModule' },
]
}
];
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(ROUTES)
],
declarations: [],
exports:[
RouterModule,
]
})
export class MainContentModule {}
In my DasboardModule
export const ROUTES: Routes = [
{
path:'dashboard', component:DashboardComponent,
children:[
{
path:'application',component:ApplicationDetailsComponent
}
]
}
]
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(ROUTES)
],
declarations: [ ],
exports:[
RouterModule,
]
})
export class DashboardModule { }
Any help would be appreciated
Add DashboardComponent in your MainContentModule declarations:
#NgModule({
imports: [
CommonModule,
RouterModule.forChild(ROUTES)
],
declarations: [DashboardComponent ],
exports:[
RouterModule,
]
})

angular2-google-maps read apikey from web.config

We intergrated angular2-google-maps in our project. The project is built angularjs 2 release version and using webapi.
app.module.ts
import { LazyMapsAPILoaderConfig, AgmCoreModule } from 'angular2-google-maps/core';
import { appConfig,IAppConfig,GoogleMapApiKey } from "./app.config";
#NgModule({
imports: [
AgmCoreModule.forRoot({
apiKey: ""
})
],
declarations: [
AppComponent
],
providers: [
{ provide: LazyMapsAPILoaderConfig, useValue: GoogleMapApiKey }
],
bootstrap: [AppComponent]
})
export class AppModule {
}
app.config.ts
import { OpaqueToken } from "#angular/core";
export let appConfig = new OpaqueToken('app.config');
export interface IAppConfig {
apiKey: string
}
export const GoogleMapApiKey : IAppConfig = {
apiKey: "Key"
};
I hardcoded the google map api key in the typescript file. Is it possible to read it from .net web.config file.
Also is this correct way of displaying the map or can i make it part of component.
Any suggestions.