I have this standalone component in angular 18: import { Component, ElementRef, OnInit, ViewChild, } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { ProductService } from '@services/product.service'; import { Product } from '@models/product.model'; import { AppModule } from './app.module'; import { MatIconModule } from '@angular/material/icon'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { UpdateProductComponent } from './modals/update.product/update.product.component'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSnackBar } from '@angular/material/snack-bar'; import { PaginatedProducts } from '@models/paginate.product.model'; @Component({ selector: 'app-root', standalone: true, templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], imports: [ MatProgressSpinnerModule, CommonModule, MatProgressSpinnerModule, AppModule, MatIconModule, MatFormFieldModule, MatDialogModule, ], }) export class AppComponent implements OnInit { isLoading = true; errorMessage = ''; products: Product[] = []; isDown = false; startX = 0; scrollLeft = 0; queryPaginationProduct: any = {}; constructor( private productService: ProductService, public dialog: MatDialog, public snackBar: MatSnackBar, ) {} ngOnInit() { this.queryPaginationProduct = { limit: 10, page: 1, total: 10, }; this.getProducts(); } getProducts() { this.isLoading = true; this.productService .getProducts( this.queryPaginationProduct.page, this.queryPaginationProduct.limit, ) .subscribe({ next: (response: PaginatedProducts) => { this.products = response.products; this.isLoading = false; this.queryPaginationProduct = { limit: response.limit, page: response.page, total: response.total, }; this.snackBar.open(response.message, 'Cerrar', { duration: 5000, horizontalPosition: 'right', verticalPosition: 'bottom', }); console.log('snackBar.open called with:', response.message); }, error: (error) => { this.errorMessage = 'Failed to load data'; this.isLoading = false; console.error(error); }, }); } onPageChange(event: any): void { this.queryPaginationProduct.page = event.pageIndex + 1; this.queryPaginationProduct.limit = event.pageSize; this.getProducts(); } trackByFn(index: any, item: Product) { return item.id; } onUpdate(item: Product) { const dialogRef = this.dialog.open(UpdateProductComponent, { width: '800px', disableClose: true, hasBackdrop: true, data: item, }); dialogRef.afterClosed().subscribe((result) => { if (result.status === 'ok') { this.getProducts(); } this.snackBar.open(result.message, 'Cerrar', { duration: 5000, horizontalPosition: 'right', verticalPosition: 'bottom', }); }); } } And I was trying to create the unit test of the function that opens the matdialog with this approach, that mocks the mat dialog component of angular material: import { TestBed, ComponentFixture } from '@angular/core/testing'; import { Subject, of } from 'rxjs'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; import { AppComponent } from './app.component'; import { UpdateProductComponent } from './modals/update.product/update.product.component'; import { Product } from '@models/product.model'; import { NoopAnimationsModule, provideAnimations } from '@angular/platform-browser/animations'; import { provideHttpClient, withFetch } from '@angular/common/http'; describe('AppComponent (fully stubbed MatDialog)', () => { let component: AppComponent; let fixture: ComponentFixture<AppComponent>; let matDialogStub: { openDialogs: MatDialogRef<any>[]; afterOpened: Subject<MatDialogRef<any>>; afterAllClosed: Subject<void>; open: jasmine.Spy; closeAll: () => void; }; let snackBar: jasmine.SpyObj<MatSnackBar>; beforeEach(async () => { const afterOpenedSubject = new Subject<MatDialogRef<any>>(); const afterAllClosedSubject = new Subject<void>(); matDialogStub = { openDialogs: [], afterOpened: afterOpenedSubject, afterAllClosed: afterAllClosedSubject, open: jasmine.createSpy('open').and.callFake((componentOrTemplateRef, config) => { const mockDialogRef = { afterClosed: () => of({ status: 'ok', message: 'Product updated successfully' }), close: () => { const index = matDialogStub.openDialogs.indexOf(mockDialogRef as any); if (index > -1) { matDialogStub.openDialogs.splice(index, 1); } if (matDialogStub.openDialogs.length === 0) { afterAllClosedSubject.next(); } }, } as MatDialogRef<UpdateProductComponent>; matDialogStub.openDialogs.push(mockDialogRef); afterOpenedSubject.next(mockDialogRef); return mockDialogRef; }), closeAll: () => { matDialogStub.openDialogs.length = 0; afterAllClosedSubject.next(); }, }; const snackBarSpy = jasmine.createSpyObj('MatSnackBar', ['open']); await TestBed.configureTestingModule({ imports: [AppComponent, UpdateProductComponent, NoopAnimationsModule], providers: [ { provide: MatDialog, useValue: matDialogStub }, { provide: MatSnackBar, useValue: snackBarSpy }, provideAnimations(), provideHttpClient(withFetch()), ], }) .overrideComponent(AppComponent, { remove: { imports: [ ], }, }) .compileComponents(); fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; snackBar = TestBed.inject(MatSnackBar) as jasmine.SpyObj<MatSnackBar>; }); it('should open UpdateProductComponent and handle afterClosed = {status: "ok"}', () => { spyOn(component, 'getProducts'); const mockProduct: Product = { id: 123, name: 'Test Product', category: 'Test Category', price: 100, quantity: 5, }; component.onUpdate(mockProduct); expect(matDialogStub.open).toHaveBeenCalledWith(UpdateProductComponent, { width: '800px', disableClose: true, hasBackdrop: true, data: mockProduct, }); expect(component.getProducts).toHaveBeenCalled(); expect(snackBar.open).toHaveBeenCalledWith( 'Product updated successfully', 'Cerrar', { duration: 5000, horizontalPosition: 'right', verticalPosition: 'bottom', } ); }); }); However, the test is not working because I got this error: Expected spy MatSnackBar.open to have been called with: [ 'Something went wrong', 'Cerrar', Object({ duration: 5000, horizontalPosition: 'right', verticalPosition: 'bottom' }) ] but it was never called. Basically none of the spies are working. Continue reading...