angulartypescriptjasminekarma-jasmineangular16

How to write unit test case for angular code


I am trying to to write test case for my angular project. I am using angular version 16. Below is my code. In my code I am not getting component.appRuleList and component.appRuleOptions values in my test case. Getting like undefined both. How to get these values inside spec.ts file

app.component.ts:

public appRuleOptions:string[] = [];
public appRuleList:any[] = [];
public selectedName = 'test';
public private:Subject<boolean> = new Subject<boolean>();

public ngOnInit(): void {
    this._store$
        .pipe(takeUntil(this.destroy), select(applicationRows))
        .subscribe((userIdentificationPart: IApplicationRule) => {
            if (userIdentificationPart && userIdentificationPart.applicationRule) { 
                this.appRuleList = userIdentificationPart.applicationRule || [];
                this.appRuleOptions = userIdentificationPart.applicationRule.map(
                    (x: IApplicationMainRules) => this.selectedName + '/' + x.name,
                );
                
            }
        });
}
 

app.component.spec.ts:

 it('should subscribe to the store and update appRuleList and appRuleOptions on ngOnInit', () => {
const applicationRule = [
 
  {
      "name": "ui",
      "place": "usa"
  }
 ];

component.selectedName = 'test';
(component['_store$'].pipe as jasmine.Spy).and.returnValue(of(applicationRule));

component.ngOnInit();

fixture.detectChanges();


expect(component.appRuleList).toEqual(applicationRule); //Getting error
expect(component.appRuleOptions).toEqual([
  "power/testing" 
]);


});

I am expecting component.appRuleList and component.appRuleOptions values in the app.component.spec.ts file.


Solution

  • First add provideMockStore to the providers array of the testing module.

    beforeEach(async () => {
      await TestBed.configureTestingModule({
        providers: [provideMockStore()],
      }).compileComponents();
    });
    

    Then get this mock store to mock the returned values.

    beforeEach(() => {
      store = TestBed.inject(MockStore);
      fixture = TestBed.createComponent(App);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });
    

    After getting the store and storing it, we can use the overrideSelector to configure the returned value.

      it('should subscribe to the store and update appRuleList and appRuleOptions on ngOnInit', fakeAsync(() => {
        const applicationRule = [
          {
            name: 'testing',
            place: 'usa',
          },
        ];
    
        component.selectedName = 'power';
        store.overrideSelector(applicationRows, {
          applicationRule,
        } as any);
    
        component.ngOnInit();
        flush();
        expect(component.appRuleList).toEqual(applicationRule); // Getting error
        expect(component.appRuleOptions).toEqual(['power/testing']);
      }));
    

    Full Code:

    import {
      TestBed,
      ComponentFixture,
      waitForAsync,
      fakeAsync,
      flush,
    } from '@angular/core/testing';
    import { MockStore, provideMockStore } from '@ngrx/store/testing';
    import { AppState, App, selectBooks } from '../main';
    
    describe('AppComponent', () => {
      let component: App;
      let fixture: ComponentFixture<App>;
      let store: MockStore<AppState>;
    
      beforeEach(async () => {
        await TestBed.configureTestingModule({
          providers: [provideMockStore()],
        }).compileComponents();
      });
    
      beforeEach(() => {
        store = TestBed.inject(MockStore);
        fixture = TestBed.createComponent(App);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it('should subscribe to the store and update appRuleList and appRuleOptions on ngOnInit', fakeAsync(() => {
        const applicationRule = [
          {
            name: 'testing',
            place: 'usa',
          },
        ];
    
        component.selectedName = 'power';
        store.overrideSelector(applicationRows, {
          applicationRule,
        } as any);
    
        component.ngOnInit();
        flush();
        expect(component.appRuleList).toEqual(applicationRule); // Getting error
        expect(component.appRuleOptions).toEqual(['power/testing']);
      }));
    });
    

    Stackblitz Demo