How to unit test MatSnackbar using Jasmine Karma in Angular

Viewed 880

I want to perform unit testing on this onSubmit function where the positive submission is leading to MatSnackbar with message, "Submitted Successfully". I am new to Jasmine Karma please guide me about the testing of MatSnackbar in this case.

Component.ts

import { MatSnackBar } from "@angular/material/snack-bar";

  constructor(
    private snackBar: MatSnackBar,
    private auth: AuthenticateService,

  ) {}
...
...
  onSubmit(e) {
    const newYellow = {
      G1: e.value.Yellow_G1,
      G2: e.value.Yellow_G2,
      G3: e.value.Yellow_G3,
      G4: e.value.Yellow_G4,
      B1: e.value.Yellow_B1,
      B2: e.value.Yellow_B2,
      B3: e.value.Yellow_B3,
      B4: e.value.Yellow_B4,
    };
    console.log(newYellow);
    this.auth.submitnominYellow(newYellow).subscribe(
      (res) => {
        console.log(res);
        this.snackBar.open("Submitted Successfully", "", {
          duration: 2000,
        });
      },
      (error) => {
        console.log(error);
      }
    );
  }

This is code for submitnomin function. auth.service.ts

submitnominYellow(inpobj) {
    console.log(inpobj);
    return this.http.post(environment.apiUrl + '/api/customize/yellow', inpobj);
}

My unit test case is somewhat like this.
component.spec.ts

    const mockSnackbarMock = jasmine.createSpyObj(['open']);
    mockSnackbarMock.open
    
    const mockopblue =
      {
        success: true
    }
    
    const MockAuthService = {
      submitnominYellow:(id) => (mockopblue),
      getuser:() => (undefined)
    
    };
...
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ YellowCustomizeComponent ],
      imports: [HttpClientTestingModule, MatSnackBarModule, FormsModule, RouterTestingModule],
      providers:[{provide: MatSnackBar, useValue: mockSnackbarMock},
      {provide: AuthenticateService, useValue: MockAuthService}
      ]

    })
    .compileComponents();
  }));
...

          fit('should open the snack bar with correct arguments when form submitted', () => {
            const e =  {
              value:{
                Yellow_G1: "YGirlName1",
                Yellow_G2: "GirlName2",
                Yellow_G3: "GirlName3",
                Yellow_G4: "GirlName4",
                Yellow_B1: "BoyName1",
                Yellow_B2: "BoyName2",
                Yellow_B3: "BoyName3",
                Yellow_B4: "BoyName4",
              }
              
            };
            component.onSubmit(e)
            console.log('mockSnackbarMock',mockSnackbarMock)
            // console.log('yellow onsubmit',component.onSubmit(e)); 
            expect(mockSnackbarMock.open).toHaveBeenCalledWith("Submitted Successfully", "", );
         })
1 Answers

in the test, it is possible to change the dependency injection configuration so that instead of the SnackBar instance the mock would be provided. That is how to do it:

const mockSnackbarMock = jasmine.createSpyObj(['open']);
mockSnackbarMock.open

await TestBed.configureTestingModule({
            declarations: [
                ...
            ],
            providers: [
                {provide: MatSnackBar, useValue: mockSnackbarMock},
            ],
            imports: [
                ...
            ],
        }).compileComponents();

Later on in the test after all the actions which trigger the snack bar, you can check if the open method was called correctly:

it('should open the snack bar with correct arguments when form submitted', () => {
   //emulate submission

   expect(mockSnackbarMock.open).toHaveBeenCalledWith("Submitted Successfully", "", {duration: 2000});
})
Related