Similar to this question, but it doesn't provide an answer that works for me.
I have a simple component that has a method that opens a dialog:
enterGiveaway() {
this.dialog.open(SpendTicketsDialogComponent, {
width: '370px',
height: '600px'
});
}
For now I just want to test that calling that method results in the dialog being opened.
The test fails with this error:
expect(spy).toBeCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
with this code:
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {GiveawayItemComponent} from './giveaway-item.component';
import {giveawaysMock} from '../../../../../mocks/giveaways.mock';
import {MaterialModule} from '../../material.module';
import {getTranslocoModule} from '../../../transloco-testing.module';
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {MatDialog} from '@angular/material/dialog';
import {EMPTY} from 'rxjs';
import {SpendTicketsDialogComponent} from '../dialogs/tickets-dialog/spend-tickets-dialog.component';
import {NumberFormatter} from '../../filters/numberFormatter/numberFormatter.filter';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {BrowserModule} from '@angular/platform-browser';
describe('GiveawayItemComponent', () => {
let component: GiveawayItemComponent;
let fixture: ComponentFixture<GiveawayItemComponent>;
let dialog: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
GiveawayItemComponent,
SpendTicketsDialogComponent,
NumberFormatter
],
imports: [
MaterialModule,
BrowserAnimationsModule,
getTranslocoModule({})
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.overrideModule(BrowserModule, {
set: {entryComponents: [SpendTicketsDialogComponent]}
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GiveawayItemComponent);
component = fixture.componentInstance;
component.giveaway = giveawaysMock[0];
component.numberOfChances = 100;
dialog = TestBed.inject(MatDialog);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('enterGiveaway', () => {
it('should open the spend tickets dialog', async(() => {
component.enterGiveaway();
fixture.detectChanges();
const spy = spyOn(dialog, 'open').and.returnValue({
afterClosed: () => EMPTY
});
expect(spy).toBeCalledTimes(1);
}));
});
});
I understand of course, that MatDialog is not referencing the actual SpendTicketsDialogComponent
which is the one that is opened. So I tried providing a mock object for the dialog:
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {GiveawayItemComponent} from './giveaway-item.component';
import {giveawaysMock} from '../../../../../mocks/giveaways.mock';
import {MaterialModule} from '../../material.module';
import {getTranslocoModule} from '../../../transloco-testing.module';
import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';
import {MatDialog} from '@angular/material/dialog';
import {of} from 'rxjs';
import {SpendTicketsDialogComponent} from '../dialogs/tickets-dialog/spend-tickets-dialog.component';
import {NumberFormatter} from '../../filters/numberFormatter/numberFormatter.filter';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {BrowserModule} from '@angular/platform-browser';
class dialogMock {
open() {
return {
afterClosed: () => of({})
};
}
}
describe('GiveawayItemComponent', () => {
let component: GiveawayItemComponent;
let fixture: ComponentFixture<GiveawayItemComponent>;
let dialog: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
GiveawayItemComponent,
SpendTicketsDialogComponent,
NumberFormatter
],
imports: [
MaterialModule,
BrowserAnimationsModule,
getTranslocoModule({})
],
providers: [{provide: MatDialog, useValue: dialogMock}],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
.overrideModule(BrowserModule, {
set: {entryComponents: [SpendTicketsDialogComponent]}
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GiveawayItemComponent);
component = fixture.componentInstance;
component.giveaway = giveawaysMock[0];
component.numberOfChances = 100;
dialog = TestBed.inject(MatDialog);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('enterGiveaway', () => {
it('should open the spend tickets dialog', async(() => {
component.enterGiveaway();
fixture.detectChanges();
const spy = spyOn(dialog, 'open').and.callThrough();
expect(spy).toBeCalledTimes(1);
}));
});
});
but this throws the error this.dialog.open is not a function
.
I actually don't think either solution is correct, because I need to check that calling enterGiveaway opens the SpendTicketsDialog.
So how can I verify that?