sgryt
sgryt

Reputation: 290

Dialog test - Jasmine returns this.store$.pipe is not a function when I mock this.store$.pipe( select(...) ...).subscribe(..)

I'm trying to unit test my component, but it immediately generates an error: TypeError: this.store$.pipe is not a function

From my understanding, createSpyObj should mock the state. I different options options but none of them worked.

@Component({
    selector: 'someSelector',
.....
})
export class SomeComponent implements OnInit, OnDestroy {

    public isCon: boolean;
    public dropdown: string[];
    private isComponentActive: boolean = true;

    constructor(@Inject(MAT_DIALOG_DATA) public data: any, private store$: Store<State>) {
        this.isCon = data.isCon;
    }

    ngOnInit(): void {
        this.store$.pipe(
            select(this.returnColumns()),
            takeWhile((): boolean => this.isComponentActive)
        ).subscribe((dropdown: []): void => this.setDropdown(dropdown));
    }

    private setDropdown(dropdown: []): void {
        this.dropdown= filter(dropdown, (key): boolean => !key.isTrue)
            .map((m): string => m.name);
    }

    private returnColumns() {
        return this.isCon ? getConCol : getEmpCol;
    }

    ngOnDestroy(): void {
        this.isComponentActive = false;
    }
}

my test:


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

    const mockDialogData: object = {
        isCon: true
    };

    const mockStoreData: ColumnDisplay[] = ['someData']
    ];
    const testStore = jasmine.createSpyObj('Store', ['select']);
    beforeEach(async () => {
        TestBed.configureTestingModule({
            declarations: [SomeComponent],
            schemas: [NO_ERRORS_SCHEMA],
            imports: [MatDialogModule],
            providers: [
                { provide: MAT_DIALOG_DATA, useValue: mockDialogData },
                { provide: Store, useValue: testStore }
            ]
        }).compileComponents();
    });

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

    it('should create', async () => {
        testStore.select.and.returnValue(from([]));
        expect(component).toBeTruthy();
    });

    it('should display correct selection rows when dialog opened', () => {
        component.ngOnInit();
        ... more assertions goes here
    });
});

Expecting to get a mock data from the store to proceed with assertions.

Upvotes: 4

Views: 5526

Answers (1)

sgryt
sgryt

Reputation: 290

I solved by mocking a store this way:

 beforeEach(() => {
    class StoreMock {
        select = jasmine.createSpy().and.returnValue(of({}));
        dispatch = jasmine.createSpy();
        pipe = jasmine.createSpy().and.returnValue(of('success'));
    }
    TestBed.configureTestingModule({
        providers: [       
            {
                provide: Store,
                useClass: StoreMock
            },
            provideMockStore()
        ]
    });

    TestBed.inject(Store);
    const store$ = TestBed.inject(Store);

Please note, now you can mock the constructor:

const testComponent = new TestComponent(store$);

Hope, that helps.

Upvotes: 1

Related Questions