Search code examples
angularangular-test

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


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?


Solution

  • 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');
      })