question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to write tests for custom components?

See original GitHub issue

Hi,

could you please provide a simple spec.ts example for custom components like ‘pink.toast.ts’. I cant figure out how to serve a provider for InjectionToken ToastConfig.

component:

import { Component, OnInit } from '@angular/core';
import { flyInOut } from './toastr.animations';
import { Toast, ToastrService, ToastPackage } from 'ngx-toastr';

@Component({
  selector: '[toastr]',
  styleUrls: ['./toastr.component.css'],
  templateUrl: './toastr.component.html',
  animations: [flyInOut],
  preserveWhitespaces: false,
})

export class ToastrComponent extends Toast implements OnInit {

  private _closeButtonClass: String;

  constructor(
    protected toastrService: ToastrService,
    public toastPackage: ToastPackage,
  ) {
    super(toastrService, toastPackage);
  }

  ngOnInit() {
    this._setButtonOrTimeOut();
    this._setLayoutsByClass();
  }

  private _setButtonOrTimeOut() {
    this.options.disableTimeOut = this.options.closeButton;
    this.options.progressBar = !this.options.closeButton;
    this.options.tapToDismiss = !this.options.closeButton;
  }

  private _setLayoutsByClass() {
    switch (this.toastClasses) {
      case 'toast-success toast':
        this._closeButtonClass = 'btn-success';
        break;
      case 'toast-warning toast':
        this._closeButtonClass = 'btn-warning';
        break;
      case 'toast-error toast':
        this._closeButtonClass = 'btn-error btn-outline';
        break;
      case 'toast-info toast':
        this._closeButtonClass = 'btn-info';
        break;
      default:
        this._closeButtonClass = 'btn-default';
        break;
    }
  }

  private _onCloseButtonClick() {
    this.toastPackage.triggerAction('closed');
    this.remove();
  }
}

test:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Toast, ToastrService, ToastPackage, ToastrModule } from 'ngx-toastr';
import { flyInOut } from './toastr.animations';
import { ToastrComponent } from './toastr.component';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ToastrModule],
      declarations: [ToastrComponent],
      providers: [ToastrService]
    })
      .compileComponents();
  }));

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

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

Error

ToastrComponent should create
Error: StaticInjectorError(DynamicTestModule)[ToastrService -> InjectionToken ToastConfig]: 
  StaticInjectorError(Platform: core)[ToastrService -> InjectionToken ToastConfig]: 
    NullInjectorError: No provider for InjectionToken ToastConfig!

Thank you and best regards Christoph

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:7
  • Comments:16

github_iconTop GitHub Comments

30reactions
trevor-hackettcommented, Feb 14, 2018

What happens if instead of importing ToastrModule, you import ToastrModule.forRoot()? The forRoot method provides 4 “services”: TOAST_CONFIG (InjectionToken), OverlayContainer, Overlay, and ToastrService. All are required for toasts to work propertly.

Maybe something like this:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ToastrModule.forRoot()],
      declarations: [ToastrComponent],
      providers: [ToastrService]
    })
      .compileComponents();
  }));
13reactions
avoermancommented, Oct 26, 2018

I hacked through it and got it to render by stubbing out ToastPackage like this:

@Injectable()
class MockToastPackage extends ToastPackage {
   constructor() {
     const toastConfig = { toastClass: 'customToast' };
     super(1, <IndividualConfig>toastConfig, 'test message', 'test title', 'show', new ToastRef(null));
   }
}

and then the module setup, just provide the mocked toastPackage

TestBed.configureTestingModule({
  imports: [ToastrModule.forRoot()],
  providers: [{ provide: ToastPackage, useClass: MockToastPackage }]
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Unit Testing Custom Components | Prismatic Docs
Learn to add unit testing to your custom components with the Jest JavaScript testing framework.
Read more >
React | Write a unit test for custom hooks in ten minutes
Before we write the first unit test, we should have a custom hooks first. If you don't understand what is the custom hooks,...
Read more >
Angular Component Testing: A Detailed How-To With Examples
To learn the basics of Angular component testing, we'll be using a brand new application created with the Angular CLI, then we'll examine...
Read more >
Picasso: Component Library Testing Made Easy - Toptal
How to Test? · States – Unit tests can help us assess if the states change accordingly, but we also need visual tests...
Read more >
How to test custom web component with jest? - Stack Overflow
JSDOM 16.2 includes basic support for custom elements and is available in Jest 26.5 and above. Here's a simple Jest test that shows...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found