puddlejumper26 / blogs

Personal Tech Blogs
4 stars 1 forks source link

How to test an @Input varaible inside Angular Testing #108

Open puddlejumper26 opened 4 years ago

puddlejumper26 commented 4 years ago

image

Often in the work, we need to test a component, which could be applied into some other component. Let say we have AppleComponent, and BananaComponent.

BananaComponent html

<apple> [newPath] = "newPath" </apple>

BananaComponent ts

public readonly newPath = '/apple/localApple'

And in this case for AppleComponent we also have a more complicated situation, which is generics, and extends from other component

AppleComponent

export AppleComponent<T, U extends FruitModel<T>>{

  @Input() public readonly updatePath! : string;

  public combinePath ( ) {
          return Location.joinWithSlash('https://localhost', this.updatePath)
  } 
}

Test

And if we need to wrtie test for combinePath function, we have two things need to deal with

apple.component.spec.ts


// first needs to mock a component for mocking the @input 
@Component({
    template:
    `<live-preview 
        [updatePath]="newPath"
        ></live-preview>`,
})
class TestWrapperComponent {
    public readonly newPath= 'testPath';
}

// second to gengerate things to cooperate with AppleComponent's generics.
describe('AppleComponent', () => {
    interface TestType {
        a: 'a';
        b: 'b';
    }
    type typeModel = AppleComponent<TestType, FruitModel<TestType>>;

    let component: typeModel;
    let fixture: ComponentFixture<TestWrapperComponent>;
    let wrapperComponent: TestWrapperComponent;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                AppleComponent,
                TestWrapperComponent,
            ],
            imports: [
                CommonModule,
                ...,
                ...,
            ],
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(TestWrapperComponent);
        wrapperComponent = fixture.componentInstance;
        component = (fixture.debugElement.childNodes[0] as DebugElement).childNodes[0].componentInstance;
    });

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

     it('should display with the correct Url when combinePath  is called', ( ) => {
          fixture.detectChanges( );
         expect(component.combinePath( )).toEqual('https://localhost'+'newPath');
     });
});

For more info, please take Unit test a component which has type extends from other component's type as reference