Unexpected issue with Mousevent method - failing to trigger

I recently created an Angular test to verify that the event method is being called. In the code snippet below, you can see that the onDialogClicked function takes a parameter of type MouseEvent, which has a stopPropagation method. However, I encountered an error when trying to fire this method and even mocking the MouseEvent did not resolve the issue.

TypeError: evt.stopPropagation is not a function

Testing Setup

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing';

import { ModalDialogConfig } from './config/modal-dialog.config';
import { SharedModule } from '../../shared.module';
import { ExampleComponent } from 'src/app/components/example/example.component';
import { ModalDialogModule } from '../../modal-dialog.module';
import { ModalDialogComponent } from './modal-dialog.component';
import { ModalDialogRef } from './config/modal-dialog-ref';
import { Observable } from 'rxjs';
import { NgxsModule } from '@ngxs/store';
import { Mock } from 'ts-mocks';


describe('ModalDialogComponent', () => {
  let component: ModalDialogComponent;
  let childComponent: ExampleComponent;
  let fixture: ComponentFixture<ModalDialogComponent>;
  let childFixture: ComponentFixture<ExampleComponent>;
  let mockMouseEvent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [SharedModule, ModalDialogModule, NgxsModule.forRoot([])],
      providers: [ModalDialogConfig, ModalDialogRef ]
    })
    .overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [ModalDialogComponent, ExampleComponent] } })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ModalDialogComponent);
    childFixture = TestBed.createComponent(ExampleComponent);
    mockMouseEvent = new Mock<MouseEvent>({ stopPropagation: () => Promise.resolve(true) });
    component = fixture.componentInstance;
    childComponent = childFixture.componentInstance;

    component.childComponentType = ExampleComponent;

    component.componentRef = childFixture.componentRef;
    spyOn(component.componentRef.instance, 'closeModal').and.returnValue(Observable.of(true));
    fixture.detectChanges();
  });


  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should call destroy ', () => {
    spyOn(component.componentRef, 'destroy').and.callThrough();
    component.ngOnDestroy();
    expect(component.componentRef.destroy).toHaveBeenCalled();
  });


  it('should trigger onDialogClicked on click', () => {
    fixture.detectChanges();

     spyOn(component, 'onDialogClicked').and.callThrough();
     const overlay = fixture.debugElement.query(By.css('.dialog'));
     overlay.triggerEventHandler('click', {});
     fixture.detectChanges();

     expect(component.onDialogClicked(mockMouseEvent)).toHaveBeenCalled();

   });

});

Component Implementation

onDialogClicked(evt: MouseEvent) {
    evt.stopPropagation();
  }

Answer №1

One common mistake is forgetting to instantiate the mock object. Instead of simply defining it, make sure to create an instance using something like:

mockMouseEvent = new Mock<MouseEvent>({ stopPropagation: () => Promise.resolve(true) });
and then access it with mockMouseEvent.Object.

In summary:

import { Mock } from 'ts-mocks';

const component = {
    onDialogClicked: function(evt) {
        evt.stopPropagation();
    }
}

describe('onDialogClicked', () => {

    let onDialogClicked;

    beforeEach(() => {
        onDialogClicked = spyOn(component, 'onDialogClicked').and.callThrough();
        const mockMouseEvent = new Mock<MouseEvent>({
            stopPropagation: () => console.log('Success!')
        });

        mouseEvent = mockMouseEvent.Object;
        onDialogClicked(mouseEvent);
    });

    it('Should have been called', () => {
        expect(onDialogClicked).toHaveBeenCalled();
    });

});

Source: Discover more in the ts-mocks documentation

Answer №2

Here is a solution that should be effective:

expect(component.onDialogClicked).toHaveBeenCalledWith(new MouseEvent('click'));

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

Accessing a user's playlist using the Spotify API - Integrating an access token in an Angular 2 HTTP request

Currently, I am enrolled in a course on Udemy that focuses on building 12 unique Angular 2 applications. One of the projects involves integrating with the Spotify Web API, and I am working on enhancing its functionality. So far, I have gained knowledge on ...

What is the best method in Angular to reset form errors after submission?

Manually setting error validation in my form using setErrors is not providing clear errors upon submission. I do not want to reset all control errors to null, as this may cancel out other existing errors on the control. After setting the error once, I ne ...

Having trouble with an Angular subscribe error that says "Property 'subscribe' does not exist on type 'AngularFireList<unknown>'.ts(2339)"? Let's find a solution together!

My goal is to retrieve data from a Firebase RDB in the data service by using the following function: this.getOrgId() .subscribe((orgId: string) => localStorage.setItem('orgId', orgId)); getOrgId() { return this.db.list(/users/${this.uId ...

Updating values - trigger modifications on each subsequent value [BehaviorSubject.onBeforeNext?]

Let's say we have a basic BehaviorSubject: this.countryOfBirth$ = new BehaviorSubject<CountryEnum>(null); get countryOfBirth() { return this.countryOfBirth$.value; }; set countryOfBirth(val: CountryEnum) { this.countryOfBirth$.next(va ...

Operators within an observable that perform actions after a specific duration has elapsed

Is there a way in an rxjs observable chain to perform a task with access to the current value of the observable after a specific time interval has elapsed? I'm essentially looking for a functionality akin to the tap operator, but one that triggers onl ...

Error in ng2-translate: TranslatePipe.transform cannot access the property 'subscribe' as it is undefined

I have been utilizing ng2-translate within my Angular 5 project and I am currently in the process of setting up a unit test for a specific component. Typically, I import TranslateModule.forRoot( *...* ) in my Tests and everything runs smoothly when using t ...

shared interfaces in a complete javascript application

In the past, I have typically used different languages for front-end and back-end development. But now, I want to explore the benefits of using JavaScript/TypeScript on both sides so that I can have key data models defined in one central location for both ...

Prevent the element attribute from being enabled before the onclick function is triggered

I am attempting to implement a feature in Angular that prevents double clicking on buttons using directives. Below is the pertinent code snippet from my template: <button (click)="onClickFunction()" appPreventDoubleClick>Add</button> And her ...

"Optimize Your Data with PrimeNG's Table Filtering Feature

I'm currently working on implementing a filter table using PrimeNG, but I'm facing an issue with the JSON structure I receive, which has multiple nested levels. Here's an example: { "id": "123", "category": "nice", "place": { "ran ...

What is the best way to receive the result of an asynchronous function as an input and showcase it using express?

I have recently started learning about node and express My goal is to create an API that can fetch data from an external source and use that data for my application Is there a way to retrieve the result of an asynchronous method and display it using the ...

Tips for eliminating white frames or borders on the Mapbox canvas map

In my current project using Angular 10, I have integrated Mapbox to display path routes. Following the standard Angular practice of splitting components, I separated the map rendering component and called it into the main map component. However, I encounte ...

After triggered window.print() in Angular, the window:afterprint event is failing to work as

I am triggering window.print() with a button click <button class="btn btn-primary" type="button" (click)="printDocument()"> Print </button> Inside the printDocument method, I open the document in a new window and ...

Having difficulty accessing JSON data from the assets folder in Angular

What I Desire:: In my project, I have a configuration file that contains URLs in a .json format. This file is stored in the asset folder. Instead of loading environments.prod or .ts files, I want to load this json configuration file and utilize it to run ...

Error message encountered when using Vue and typescript: "TypeError: Object prototype may only be an Object or null: undefined"

Encountered a TypeError: Object prototype may only be an Object or null: undefined I ran into an issue while working on my project. I'm utilizing vuejs, typescript, and jest. Despite having simple code, I encountered an error when trying to unit tes ...

Understanding the mechanics of promises in Typescript amidst encountering a MySQL error

I am currently developing an application in Angular 8.3 with Node.js 10.17 and MySQL. When attempting to send JSON data to the Backend, I encountered an error with promises that I am struggling to resolve. I have conducted thorough research but still can ...

Typescript Factory Creation by Leveraging infer and typeof

Primary Objective: My main focus is to grasp the concept of creating a Factory in Typescript, not just copying and pasting code. I am specifically struggling with understanding types and type inference. My goal is to have a "MyCloner" class that can genera ...

TSLint in TypeScript showing unexpected results

In the process of developing a project using Angular, I recently made the switch from VS Code to WebStorm. Unfortunately, I'm encountering some difficulties that I can't seem to make sense of. To ensure everything is functioning correctly, I perf ...

Creating a dynamic group in JSPlumb for Angular and adding nodes to it after the group has been successfully created in Angular 7

I am attempting to create a jsplumb group and then dynamically add nodes to it. However, I have encountered an issue where the documentation states that a node must be created first before being added to the group. In my case, I need to add the group first ...

Transforming this JavaScript function using Template Strings into TypeScript

Is there anyone out there who can assist with the following query? I have a functional .js file that I need to integrate into a TypeScript program. import React from "react"; import styled, { css } from "styled-components"; const style = ({ theme, ...res ...

Tips on using dual drop-down menus for sorting options

I am encountering a small issue with my two filters. When I choose the values IN and ENCODE, all the values are displayed correctly... https://i.sstatic.net/Uoido.png However, the problem arises when I click on OUT, as the status is not displayed correc ...