Checking to see if the prop 'isChecked' has been modified

I'm currently facing a challenge with testing whether a class's prop value changes after clicking the switcher.

Below is the component class I am working with:

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';

@Component({
selector: 'sps-flow-asset-switcher',
templateUrl: './flow-asset-switcher.component.html',
styleUrls: ['./flow-asset-switcher.component.scss'],
})

export class FlowAssetSwitcherComponent implements OnInit {

@Input() isChecked: boolean;
@Output() checkedChange = new EventEmitter<boolean>();

constructor() { }

ngOnInit() {}

onChange(e): void {
    this.isChecked = e.target.checked;
    this.checkedChange.emit(this.isChecked);
  }
}

Here is the template used for this component:

<label class="switcher">
  <input
    type="checkbox"
    [checked]="isChecked"
    (change)="onChange($event)"
   />
  <span class="switcher__slider"></span>
</label>

When it comes to testing, I have started with the following approach:

import { async, ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';

import { FlowAssetSwitcherComponent } from './flow-asset-switcher.component';

fdescribe('FlowAssetSwitcherComponent', () => {
let component: FlowAssetSwitcherComponent;
let fixture: ComponentFixture<FlowAssetSwitcherComponent>;

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [FormsModule],
        declarations: [FlowAssetSwitcherComponent],
    })
        .compileComponents();
}));

// Additional test cases are included here...

});

My main goal in testing is to ensure that the prop value changes as expected after certain actions. However, I have encountered an issue when the initial prop value is set to false and needs to be changed to true upon user interaction. This seems to cause the test to fail unexpectedly.

Therefore, my primary question is: What is the best approach to verify if a prop value has been successfully changed after a specific action, such as a click event?

Furthermore, I would appreciate guidance on the correct methods for testing components, especially since this is my first attempt at writing tests.

Answer №1

If you're wondering how to approach this task, I recommend keeping it simple with the following steps:

  • After setting the value of isChecked, make sure to call fixture.detectChanges() to update the input element accordingly.
  • Simply triggering a change event without any actual changes won't be effective. Instead, try clicking on the input element to initiate the desired change.
  • Since there are no asynchronous operations involved, there's no need for async().

To see these suggestions in action, you can check out this sample test on StackBlitz. Here's how your test spec could look like with the proposed changes:

it('should change isChecked from false to true when switcher clicked', () => {
    const inputEl = fixture.debugElement.nativeElement.querySelector('input');
    component.isChecked = false;
    fixture.detectChanges(); // Make sure to invoke detectChanges() after updating 'isChecked'

    // inputEl.dispatchEvent(new Event('change')); // <-- No need for this
    inputEl.click(); // Simply trigger a click event on the inputElement
    expect(component.isChecked)
        .toEqual(true);
});

I also want to thank you for providing all the necessary details in your question! It greatly helped in creating a Stackblitz for testing purposes.

I hope this information proves useful to 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

The error message "Unable to find 'encoding'" in NextJS is triggered by the use of try/require in the node_modules folder

Running a NextJS app in typescript with version 13.4.19, utilizing @apollo/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0d7e687f7b687f4d392334233e">[email protected]</a> triggers a warning during the build proce ...

How to retrieve the filename from a URL using Node.js

In my Node.js script, I have the following type of link: 148414929_307508464041827_8013797938118488137_n.mp4.m4a?_nc_ht=scontent-mxp1-1.cdninstagram.com&_nc_ohc=_--i1eVUUXoAX9lJQ-u&ccb=7-4&oe=60835C8D&oh=61973532a48cb4fb62ac6711e7eba82f& ...

Puppeteer encountered an error when trying to evaluate the script: ReferenceError: TABLE_ROW_SELECTOR was not defined

https://i.stack.imgur.com/PJYUf.jpg Recently, I started exploring pupeteer and node while using vscode. My goal is to log into a website and scrape a table. So far, this is what I have: (async () => { const browser = await puppeteer.launch({ headle ...

Server-side issue: Ajax POST request returns an empty POST array

I've encountered an issue with my JavaScript function that is supposed to collect data and send it to a PHP file. My problem lies in attempting to submit an array as part of the post: Here's the snippet of the function in question: var string ...

What is the best approach to execute this function repeatedly at specific intervals?

I'm attempting to execute everything inside the checkUser() function, but it's not running at the specified interval. Is there a more efficient way to achieve this? My goal is to verify the address every few minutes. The line const accounts = awa ...

Authenticating Keycloak Object in Angular 2 - Verify the Authenticated Status

Incorporating the Keycloak authentication service into my Angular 2 project has been a learning experience. I have set up a service to handle logging in and out functionalities. Successfully authenticating a user and logging them out was relatively smooth ...

Tips for passing parameters from an anchor click event in TypeScript

Is it possible to send parameters to a click event from an anchor element, or should we not pass params at all? Here is the function I am using: const slideShow = (e: React.MouseEvent<HTMLAnchorElement> | undefined): void => { console.lo ...

Unable to access the variable field of MongoDB in JavaScript

I'm facing an issue while trying to loop through an array I retrieved from mongodb. It seems the array is treated as a single element, and here is the code snippet: const project = await Project.findOne({ embedId: inititalData.embedId }); console. ...

CDNify load error causing Grunt Serve to fail

I have encountered an issue with a freshly installed Angular project. When I try to run the grunt serve command, I receive the following error: I am currently using Node 12.6.1 with Source Tree and have confirmed that Bower is properly installed. Loading ...

Updating the ngModel within a directive using another directive

Struggling to grasp why modifications to an ngModel don't transfer between directives. Take a look at this plunker for a simplified example of the issue. Essentially, there's a directive I've defined that utilizes ngModel with an isolate sc ...

Naming convention for TypeScript accessors

Expanding on the previous solution When I convert the example object to JSON from the answer above: JSON.stringify(obj) The output is: {"_id":"3457"} If I intend to transmit this data over a service and store it in a database, I prefer not to use the ...

Retrieving the real server response using Angular's $resource

I have developed an API using Laravel which provides JSON data in the following format: { "data":{ "errors":{ "username":"The username you entered has already been taken.", "email":"The email address provided is already in use." } ...

Link scripts can sometimes cause issues with node.js

Greetings! I have successfully created a client-side SPA using vanilla-router. However, my Node.js server sometimes encounters an error when attempting to load a linked script. Uncaught SyntaxError: Unexpected token '<' This error only oc ...

Problem identified with Vue.js: The Log in screen briefly flashes before redirecting the authenticated user (resulting in a full page refresh)

My routing is functioning properly, utilizing navigation guards to prevent users from accessing the login or register routes once they are signed in. However, when I manually type '/auth/signin' in the address bar, the login screen briefly appear ...

Coordinate the timing of CSS animation with the loading of the page

Despite the abundance of similar questions, none have quite addressed my specific query. I've created a preloader using CSS animation and I want it to synchronize perfectly with the page load. While I can trigger the animation on page load, I'm s ...

Generating replicated elements at varying positions

After discovering that my previous question, which can be found here, is currently not feasible due to limitations with html2canvas only taking 'snapshots', I have chosen to approach the problem differently. The new approach involves making an o ...

What are effective ways to eliminate cross-origin request restrictions in Chrome?

Just starting out with angular and trying to incorporate a templateUrl in an angular directive. However, when attempting to view the local html file in the browser, I encounter the following errors --> XMLHttpRequest cannot load file:///Users/suparnade ...

How does the 'snack bar message' get automatically assigned without being explicitly defined in the 'data' function?

As a novice in web development and Vue, I am currently engaged in a simple project using Vuetify with Vue.JS 3. Within one of my views, there is a table that triggers a message and fetches status to display a snackbar to the user: methods: { async fetc ...

Why is it necessary to include a dollar sign before interpolation in Angular?

While diving into a tutorial, I stumbled upon a piece of code that piqued my curiosity. I grasped the concept that appending a dollar sign as a suffix indicates observability, but I wonder why the dollar sign was also prefixed to this.log(`updated hero i ...

tips on how to shade a column in the material data table according to a specific condition when the table is first loaded

Is there a way to automatically highlight certain rows in the angular material data table based on specific column values when the table loads? Let's take a look at an example component below: @Component({ selector: 'table-basic-example', ...