How i can change the @Input values for each test in anagular?

46 Views Asked by At

i'm a starter in angular testing and i have some problems to test my components.

How i can change my @Input values from my component under test?

Here is my component test code:

I'm using the Angular version 16.

import { ComponentFixture, TestBed } from '@angular/core/testing';
 
import { IconComponent } from '@shared/icon/icon.component';
import { SvgIconComponent } from 'angular-svg-icon';
import { MockComponent } from 'ng-mocks';
 
describe('IconComponent', () => {
  let component: IconComponent;
  let fixture: ComponentFixture<IconComponent>
 
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [IconComponent],
      providers: [],
    })
    .overrideComponent(IconComponent, {
      remove: {
        imports: [SvgIconComponent]
      },
      add: {
        imports: [MockComponent(SvgIconComponent)]
      }
    })
    .compileComponents();
 
    fixture = TestBed.createComponent(IconComponent);
    component = fixture.componentInstance;
 
    // here i set my @Input values for this test

    component.icon = 'icon';
    component.height = 25;
    component.width = 25;
    component.svgClass = 'svgClass';
 
    fixture.detectChanges();
  });
 
  it('should create the icon component', () => {
    expect(component).toBeTruthy();
  });
 
  it('should create the component with correctly data', () => {
 
    expect(component.iconPath).toBe('assets/svg/ic-icon.svg');
    expect(component.viewBox).toBe('0 0 25 25');
  })
});

But, if i add a new test and a i need to test with another @Input values, how i do it?

2

There are 2 best solutions below

2
On BEST ANSWER

That depends. If you need the during initialization of the component I usually move the fixture.detectChanges() in each test like this:

import { ComponentFixture, TestBed } from '@angular/core/testing';
 
import { IconComponent } from '@shared/icon/icon.component';
import { SvgIconComponent } from 'angular-svg-icon';
import { MockComponent } from 'ng-mocks';
 
describe('IconComponent', () => {
  let component: IconComponent;
  let fixture: ComponentFixture<IconComponent>
 
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [IconComponent],
      providers: [],
    })
    .overrideComponent(IconComponent, {
      remove: {
        imports: [SvgIconComponent]
      },
      add: {
        imports: [MockComponent(SvgIconComponent)]
      }
    })
    .compileComponents();
 
    fixture = TestBed.createComponent(IconComponent);
    component = fixture.componentInstance;
 
    // Setting default values

    component.icon = 'icon';
    component.height = 25;
    component.width = 25;
    component.svgClass = 'svgClass';
  });
 
  it('should create the icon component', () => {
    fixture.detectChanges();
    expect(component).toBeTruthy();
  });
 
  it('should create the component with correctly data', () => {
    fixture.detectChanges();
 
    expect(component.iconPath).toBe('assets/svg/ic-icon.svg');
    expect(component.viewBox).toBe('0 0 25 25');
  })
 
  it('should create the component with different data', () => {
    component.icon = 'icon';
    component.height = 40;
    component.width = 40;
    component.svgClass = 'svgClass';

    fixture.detectChanges();
 
    expect(component.iconPath).toBe('assets/svg/ic-icon.svg');
    expect(component.viewBox).toBe('0 0 40 40');
  })
});

This works because your component does not get initialized before you call fixture.detectChanges() the first time.

However if you don't need the input variables to be different at the initialization, you can simply just change them at any point in the test and then call fixture.detectChanges() like so:

  it('should create the component with dfifferent data', () => {
    component.icon = 'icon';
    component.height = 40;
    component.width = 40;
    component.svgClass = 'svgClass';

    fixture.detectChanges();
 
    expect(component.iconPath).toBe('assets/svg/ic-icon.svg');
    expect(component.viewBox).toBe('0 0 40 40');

    component.height = 50;
    component.width = 50;

    fixture.detectChanges();
 
    expect(component.iconPath).toBe('assets/svg/ic-icon.svg');
    expect(component.viewBox).toBe('0 0 50 50');
  })
0
On

You can use nested describes with own beforeEach, just as one possibility.

describe('IconComponent', () => {
  let component: IconComponent;
  let fixture: ComponentFixture<IconComponent>
 
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [IconComponent],
      providers: [],
    })
    .overrideComponent(IconComponent, {
      remove: {
        imports: [SvgIconComponent]
      },
      add: {
        imports: [MockComponent(SvgIconComponent)]
      }
    })
    .compileComponents();
 
    fixture = TestBed.createComponent(IconComponent);
    component = fixture.componentInstance;
 
    // remove the inputs here
  });
 
  it('should create the icon component', () => {
    expect(component).toBeTruthy();
  });

  describe('Testblock 1', () => {
    beforeEach(() => {
      component.icon = 'icon';
      component.height = 25;
      component.width = 25;
      component.svgClass = 'svgClass';
 
      fixture.detectChanges();
    });

    it('should create the component with correctly data', () => {
      expect(component.iconPath).toBe('assets/svg/ic-icon.svg');
      expect(component.viewBox).toBe('0 0 25 25');
    })

    // more it
  });
 
  // more test blocks
});