NullInjectorError: No provider for InjectionToken ToastConfig! in jasmine spec for Angular + Electron project
Asked Answered
B

7

33

The problem

Hi everybody! First time asking question here, hoping for some help. I'm currently developing a Electron+Angular application and I'm finally preparing for testing all the services and components. In trying to launch samples specs created with WebStorm along with components and services I'm facing the current error:

NullInjectorError: StaticInjectorError(DynamicTestModule)[InjectionToken ToastConfig]: 
      StaticInjectorError(Platform: core)[InjectionToken ToastConfig]: 
        NullInjectorError: No provider for InjectionToken ToastConfig!

This is the simple test file I'm trying to run

import {TestBed} from '@angular/core/testing';
import {CognitoService} from './cognito.service';
import {ToastrModule, ToastrService} from 'ngx-toastr';

describe('CognitoService', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ToastrModule.forRoot()],
      providers: [
        CognitoService,
        {provide: ToastrService, useClass: ToastrService}
      ]
    }).compileComponents();
  });

  it('should be created', () => {
    const service: CognitoService = TestBed.get(CognitoService);
    expect(service).toBeTruthy();
  });

});

This is the stacktrace I've obtained from running the test

NullInjectorError: StaticInjectorError(DynamicTestModule)[InjectionToken ToastConfig]: 
      StaticInjectorError(Platform: core)[InjectionToken ToastConfig]: 
        NullInjectorError: No provider for InjectionToken ToastConfig!
    error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ InjectionToken ToastConfig ] })
        at <Jasmine>
        at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:724:1)
        at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:2093:1)
        at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:2037:1)
        at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:1941:1)
        at resolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:2093:1)
        at tryResolveToken (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:2037:1)
        at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:1941:1)
        at resolveNgModuleDep (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:20895:1)
        at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:21584:1)
        at injectInjectorOnly (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm5/core.js:627:1)

This is the current app module I have in the solution, as I've seen that it may depends on importing correctly ToastrModule here

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { ModalModule, TooltipModule } from 'ngx-bootstrap';
import { ToastrModule } from 'ngx-toastr';
import { LayoutModule } from './layout/layout.module';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ConfirmationDialogComponent } from './shared/confirmation-dialog/confirmation-dialog.component';
import {SharedModule} from './shared/shared.module';

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    NoopAnimationsModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    HttpClientModule,
    SharedModule,
    LayoutModule,
    ToastrModule.forRoot({
      positionClass: 'toast-top-full-width'
    }),
    TooltipModule.forRoot(),
    ModalModule.forRoot(),
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    }),
  ],
  entryComponents: [ConfirmationDialogComponent],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

What I've tried

  • Verified that ToastrModule.forRootis in the import section

  • Removed / Added "jasmine", "jest" in tsconfig.spec.json which is an extension of

    tsconfig.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": [
      "jasmine",
      "node"
    ]
  },
  "files": [
    "src/test.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}
  • Tried npm update
  • Tried to install @types/jasmine and @types/jest

Any help would be appreciated, thanks in advance!

PS: if you need further information, I'll try to add them as soon as possible

Brawn answered 15/7, 2020 at 12:39 Comment(0)
S
30

Try to specify the position of toaster otherwise it will give null Inject error

app.module.ts

 imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    BrowserAnimationsModule,
    FormsModule,
    BsDropdownModule.forRoot(),
    ToastrModule.forRoot({
      positionClass :'toast-bottom-right'
    })
  ],
Splendent answered 6/11, 2020 at 11:7 Comment(0)
I
16
const toastrService = {
  success: (
    message?: string,
    title?: string,
    override?: Partial<IndividualConfig>
  ) => {},
  error: (
    message?: string,
    title?: string,
    override?: Partial<IndividualConfig>
  ) => {},
};

Use the stub inside provider array

{ provide: ToastrService, useValue: toastrService }
Irrecoverable answered 5/10, 2020 at 18:3 Comment(1)
I'd suggest using MockService(ToastrService) to create a full mock automatically.Uproot
P
6

Adding ToastrModule.forRoot() to my.component.spec.ts works for me

beforeEach(waitForAsync(() => {
  TestBed.configureTestingModule({
    declarations: [ LoginComponent ],
    imports: [
      IonicModule.forRoot(),
      ToastrModule.forRoot() // added this works for me
    ], ...
Prompt answered 9/9, 2022 at 2:2 Comment(0)
C
2

Couldn't replicate but using ToastrModule.forRoot() works for me .

But I did it stubbing my custom service wrapped around Toastr and used it like this .

 providers: [
    { provide : ToasterNotificationService,
      useClass : ToasterStub
    }
  ]

ToasterStub class is :

class ToasterStub {
 showSuccess(message: string, title: string): void {}
 showError(message: string, title: string): void {}
 showInfo(message: string, title: string): void {}
 showWarning(message: string, title: string): void {}
}
Cinereous answered 11/3, 2021 at 15:31 Comment(0)
R
0

Sometimes this error shows due to Toastr version compatibility issues with the Angular version. I also got the same kind of error and it solved after when i changed it to Toastr version to "^10.0.4"

Reg answered 20/11, 2020 at 1:34 Comment(0)
W
0

I had this issue because I was testing library linked with other library and I have forgotten to add "preserveSymlinks": true, into angular.json and tsconfig.lib.json.

Warring answered 16/7, 2021 at 11:38 Comment(0)
K
0

Using angular 18, and toastr version 19!

Just go into the app.config.ts file under the app folder and add this line inside the providers array:

export const appConfig: ApplicationConfig = {
providers: [
.
provideToastr({}),
.
};

Its using this import: import { provideToastr } from 'ngx-toastr';

Koblas answered 14/7 at 14:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.