Exploring the functionality of the Angular snackbar feature

I have created a simple snackbar with the following code:

app.component.ts:

  ngOnInit(){
    this.dataService.valueChanges.pipe(
        filter((data) => data === true),
        switchMap(() => {
          const snackBarRef = this.matSnackBar.open(
            'A new value updated',
            'OK',
            {
              duration: 3000
            }
          );

          return snackBarRef.onAction();
        })
      )
      .subscribe(() => {
        this.window.location.reload();
      });
  }

app.component.spec.ts (Including mock data for service)

describe('AppComponent', () => { 
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;
  let matSnackBarSpy: jasmine.SpyObj<MatSnackBar>;

  let a = "";
  let b = "";
  let c = "";

  const mockDataService = {
    valueChanges: of(true)
  };

  beforeEach(async(() => {
    TestBed.configureTestingModule({

    a = "Test";
    b = "X";
    c = "suc";
    matSnackBarSpy = TestBed.get<MatSnackBar>(MatSnackBar);

 })
}))

  describe('#ngOnInit()', () => {

    it('should call MatSnackBar.open()', async(done: DoneFn) => {
      const error = new HttpErrorResponse({ error: 'Some error' });

      component.ngOnInit();

      expect(mockDataService.valueChanges).toBeTruthy();
      expect(matSnackBarSpy.open(a,b,c)).toBeTruthy();

      done();
    });
  });

})

data.service.ts

import { Observable } from 'rxjs';

export class DataService {
  valueChanges: Observable<boolean>;
}

Explanation:

  • I have a service with a property valueChanges of type Observable<boolean>.

  • In the component.ts, I receive boolean value true after the value change and the snackbar opens successfully.

  • Currently, I am working on implementing test cases in component.spec.ts,

      expect(mockDataService.valueChanges).toBeTruthy();
      expect(matSnackBarSpy.open(a,b,c)).toBeTruthy();
    

Although the tests are passing, I consistently see a warning in Chrome as depicted below.

  • Despite referencing Mocking MatSnackBar in Angular 8 & Jasmine, I am unable to resolve the issue.

Requirement: I aim to cover all the tests that currently show warnings indicating they are not covered, as displayed in the image above.

Even though the test cases pass, the test coverage report still shows function not covered and statement not covered warnings when accessing index.html of the component.

Answer №1

When testing, it's important to check if the matSnackBar methods are being called correctly. It's worth noting that testing the behavior of matSnackBar does not fall under unit testing.

To do this, you can create a MatSnackBarStub class:

class MatSnackBarStub{
  open(){
    return {
      onAction: () => of({})
    };
  }
}

You can then use this in your component.spec file:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [SomeComponent],
    providers: [{provide: MatSnackBar , useClass: MatSnackBarStub}]
  }).compileComponents();
}));

it('should create', () => {
  spyOn(component.matSnackBar,"open").and.callThrough();
  component.ngOnInit();
  expect(component.matSnackBar.open).toHaveBeenCalled();
  // you can also use ".toHaveBeenCalledWith" with necessary params
});

If you're looking for more resources on unit testing using jasmine and karma, I recommend checking out this collection of articles. There is a guide on how to use stubs and spies which might be helpful for you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

transitioning from angular cli version 1.7 to version 12

Looking for a detailed guide on upgrading from version 1.7 to the latest Angular version (12/11)? I currently have an app running on version 1.7 and couldn't find a step-by-step process here: upgrading angular Would it be safe to assume that the upgr ...

Can someone guide me on identifying the type of object in React/Typescript?

Can anyone help me remove this unnecessary definition? const [nextLocation, setNextLocation] = useState(null) as any[]; I have been struggling with this in my React Router 6 project. I've looked through the documentation but haven't found a suit ...

Combining and linking 3 RxJS Observables in TypeScript and Angular 4 without nesting to achieve dependencies in the result

I have 3 observables that need to be chained together, with the result from the first one used in the other 2. They must run sequentially and each one should wait for the previous one to complete before starting. Is there a way to chain them without nestin ...

Encountering issues when passing a string as query parameters

How can I successfully pass a string value along with navigation from one component to another using query parameters? Component1: stringData = "Hello"; this.router.navigate(['component2'], { queryParams: stringData }); Component2: ...

Error message: Cypress Vue component test fails due to the inability to import the Ref type (export named 'Ref' is missing)

Recently, I created a Cypress component test for my Vue component by mounting it and verifying its existence. The component utilizes Vue's Ref type and is structured as a TypeScript component. However, during the test execution, Cypress encountered a ...

Angular input material with a stylish twist

How can I style all inputs on the Angular Material input component (matInput) using Typescript? I attempted to implement this solution, but it only affects the first element. ngAfterViewInit () { const matlabel = this.elRef.nativeElement.querySelecto ...

Measuring the height of an element within its parent component using Angular 4

Check out my demo here I've created a basic parent component along with a child component. Is there a way to retrieve the height of the parent div from within the child component? import { Component, Input, ElementRef, OnInit, ViewChild } from &apo ...

Can you explain the meaning of `(error: T) => void` in error?

I've come across this particular syntax in a few Typescript libraries and I am trying to grasp its meaning. error?: (error: T) => void I have seen it being used like so: class SomeClass { someFunction(error?: (error: T) => void){ } ...

The problem with MUI SwipeableDrawer not being recognized as a JSX.Element

Currently, I am implementing the SwipeableDrawer component in my project. However, an issue arises during the build process specifically related to the typings. I have made the effort to update both @types/react and @types/react-dom to version 18, but unf ...

Angular 2 - Graphic Representation Tool for Visualizing Workflows and Processes - Resource Center

Looking for a library that can meet specific requirements related to diagram creation and rendering. We have explored jsplumbtoolkit, mermaid, and gojs, but none of these fully satisfy our needs. For example, we need the ability to dynamically change con ...

Create a line break in the React Mui DataGrid to ensure that when the text inside a row reaches its maximum

I'm facing an issue with a table created using MUI DataGrid. When user input is too long, the text gets truncated with "..." at the end. My goal is to have the text break into multiple lines within the column, similar to this example: I want the text ...

Customize the size of data points on your Angular 2 chart with variable

In my Angular 2 application, I am utilizing ng2-charts to create a line chart. The chart functions properly, showing a change in color when hovering over a point with the mouse. However, I want to replicate this behavior manually through code. Upon clicki ...

The parameter '{ validator: any; }' cannot be assigned to the ValidatorFn type in this context

I am currently experiencing a challenge while attempting to create a custom validator using Angular. I have created a form for my sign-up page and wanted to ensure that the password and confirm password fields match by implementing a custom validator. Des ...

What kind of ng-template is used for enforcing strict typing in Angular?

I have an Angular application running on version 14, and let's consider a component inside it where I have the following HTML: <button (click)="myfn(template)">Click Me</button> <ng-template #template> <some html here& ...

I am completely baffled by the meaning of this Typescript error

In my code, there is a button component setup like this: export interface ButtonProps { kind?: 'normal' | 'flat' | 'primary'; negative?: boolean; size?: 'small' | 'big'; spinner?: boolean; ...

Prepare fixtures for commands in Cypress before executing the hook

One of my main tasks is to load the fixtures file only once and ensure it is accessible across all project files. To achieve this, I created a fixtures.js file with the following content: let fixturesData; export const loadFixturesData = () => { cy ...

Encountering an issue with Jest when using jest.spyOn() and mockReturnValueOnce causing an error

jest --passWithNoTests --silent --noStackTrace --runInBand --watch -c jest-unit-config.js Project repository An error occurred at jest.spyOn(bcrypt, 'hash').mockRejectedValue(new Error('Async error message')) Error TS2345: The argum ...

Displaying exclusively the country code in an Angular material-select component

This is the HTML code I am using: <mat-form-field style="width: 70px;margin-left: 50px;"> <mat-label>Select an option</mat-label> <mat-select (openedChange)="toogleCountry()" [(value)]="selected"> <mat-option value="+91" ...

Deleting the First Item from an Array in Typescript using Angular

Clicking my Button in .html <button (click)="deleteFirst()">Delete First</button> My array setup and removal function in .ts: people = [ {first: "Tom", last: "Brown"}, {first: "Ben", last: &qu ...

I am looking to implement tab navigation for page switching in my project, which is built with react-redux and react-router

Explore the Material-UI Tabs component here Currently, I am implementing a React application with Redux. My goal is to utilize a panelTab from Material UI in order to navigate between different React pages. Whenever a tab is clicked, <TabPanel value ...