Unit testing the TypeScript function with Karma, which takes NgForm as a parameter

As I work on writing unit tests for a specific method, I encounter the following code:

public addCred:boolean=true;
public credName:any;

public addMachineCredential(credentialForm: NgForm) {
    this.addCred = true;
    this.credName = credentialForm.value.name;
}

When attempting to test this function in my test class, I run into an issue:

it('should add machine credential', () => {
    var machineCredentialForm: NgForm = new NgForm(null, null);
    machineCredentialForm.controls['name'].setValue('name');
    machineCredentialForm.controls['username'].setValue('username');
    machineCredentialForm.controls['password'].setValue('password');
    component.addMachineCredential(machineCredentialForm);
    expect(component.addCred).toBe(true);
    expect(component.credName).toBe("name");
});

An error occurs stating:

TypeError: Cannot read property 'setValue' of undefined

I am seeking advice on properly testing the "addMachineCredential" function.

Answer №1

If you want to perform unit testing on the module, it is recommended to utilize ReactiveForms instead of Template driven forms as suggested in the comment. I have refactored the code and provided an example based on the snippet you shared. Here is a possible solution:

Here is one approach to refactor your code to ensure its functionality:

Your component:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-unit-test',
  template: `
  <p>Works</p>
  `,
  styleUrls: ['./unit-test.component.css']
})
export class UnitTestComponent {
  public addCred: boolean = true;
  public credName: any;

  form: FormGroup = new FormGroup({
    name: new FormControl('', [])
  });

  constructor() {}

  public addMachineCredential(credentialForm: FormGroup) {
    this.addCred = true;
    this.credName = credentialForm.controls.name.value;
  }
}

Your spec file:

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

import { UnitTestComponent } from './unit-test.component';

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

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

  beforeEach(() => {
    fixture = TestBed.createComponent(UnitTestComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should add machine credential', () => {
    component.form.controls.name.setValue('name');
    component.addMachineCredential(component.form);
    expect(component.addCred).toBe(true);
    expect(component.credName).toBe('name');
  });
});

Keep in mind that your component module must declare ReactiveFormsModule, so..

Your module:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { UnitTestComponent } from './Questions/unit-test/unit-test.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent,
    UnitTestComponent,
    FormsModule,
    ReactiveFormsModule
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

I hope this explanation proves helpful.

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

Creating getter and setter functions for an input field model property in Angular

I need help creating getter and setter methods for an input field property. Here is my attempted code: import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', st ...

Manipulating a DOM element in Angular 2 to alter its class attribute

I am a beginner in angular2. Here is my code: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'main', template: ` <div class="current"> </div> ` }) export class MainComponent impl ...

Error: Found an unconventional token "e" in JSON data at position 1 during parsing in JSON.parse function

Is there a way to retrieve a string value by calling an API in Angular? Here is my approach: Service file - public getRespondDashboardUrl(): Observable<any> { return this.http.get(`ref/RespondDashboardUrl`); } Component File respondDashboar ...

Error NG0304: The element 'mat-select' is not recognized in the template of the 'LoginPage' component

After creating a basic app, I decided to incorporate Angular Material into my project. The app in question is an Ionic 6 / Angular 14 app, however, I encountered an error while attempting to implement mat-select: To address this issue, I made sure to incl ...

A guide on streamlining the process of generating "this." variables within Angular

When it comes to working with Javascript, particularly Angular, I find myself using the this. syntax quite often. I'm curious to know if it's possible to concatenate variables in order to create a this. variable. For instance, is this achievab ...

Enhancing data validation and converting strings to dates with Nest.js - DTO approach

Anticipating the upcoming request to adhere to the ISO 8601 standard timestamp format, something similar to "2023-12-04T15:30:00Z" (typically embedded as a string within JSON data that needs conversion to a JavaScript Date object). This is my Data Transfe ...

Using TypeScript's conditional types for assigning types in React

I'm tasked with creating a component that can belong to two different types. Let's call them Type A = { a: SomeCustomType } Type B = { b: SomeOtherDifferentType } Based on my understanding, I can define the type of this component as function C ...

The circular reference error in Typescript occurs when a class extends a value that is either undefined, not a constructor,

Let me begin by sharing some context: I am currently employed at a company where I have taken over the codebase. To better understand the issue, I decided to replicate it in a new nestjs project, which involves 4 entities (for demonstration purposes only). ...

Tips for identifying unnecessary async statements in TypeScript code?

We have been encountering challenges in our app due to developers using async unnecessarily, particularly when the code is actually synchronous. This has led to issues like code running out of order and boolean statements returning unexpected results, espe ...

Preventing long int types from being stored as strings in IndexedDB

The behavior of IndexedDB is causing some unexpected results. When attempting to store a long integer number, it is being stored as a string. This can cause issues with indexing and sorting the data. For instance: const data: { id: string, dateCreated ...

Angular: The unexpected emergence of certificate issues and the ensuing challenges in resolving them

After completing the first two chapters of Google's Tour of Heroes, I repeated the process 21 times without any major issues. However, when attempting to run it for the 22nd time on the same machine and with the same Visual Studio setup, I encountered ...

The attribute 'X' is not found in the type 'HTMLAttributes<HTMLDivElement>'.ts(2322)

Encountered an issue using JSX sample code in TSX, resulting in the following error: (property) use:sortable: true Type '{ children: any; "use:sortable": true; class: string; classList: { "opacity-25": boolean; "transition-tr ...

Mixing Jest and Cypress in a TypeScript environment can lead to Assertion and JestMatchers issues

When utilizing [email protected] alongside Jest, we are encountering TypeScript errors related to Assertion and JestMatchers. What is the reason for these TypeScript errors when using Jest and [email protected] in the same project? ...

Dropdown element with PrimeNG adorned with a span

I am trying to create a simple form with text inputs and dropdowns. I have successfully implemented the textInput, but I am struggling with the dropdowns. Below is the code that I have so far: <div class="p-grid p-dir-col p-offset-2"> ...

Mastering unit testing with Behaviour Subjects in Angular

I am looking to test the get and set methods of my user.store.ts file. The get() method is used to retrieve users, while addUsers() is utilized to add new Users to the BehaviorSubject. How can I accomplish this? import { Injectable } from '@angular/c ...

What ways can I dynamically implement styles using ngStyle in Angular?

Is there a way to toggle the position value from left to right based on a boolean condition? I am looking to switch [ngStyle]="{ 'left.px': offSetX } with [ngStyle]="{ 'right.px': offSetX } depending on a certain condition import { C ...

Cypress error: Unable to access 'uid' property as it is undefined

Recently in my Cypress project with TypeScript support utilizing the Cucumber Preprocessor, an unexpected exception has started appearing: TypeError: Cannot read properties of undefined (reading 'uid') There are instances where changing to a di ...

Issue with exclude not functioning in tsconfig.json for Angular Typescript deployment

I am encountering an issue with a module within the node_modules directory while compiling my Angular 4 project. The error messages I'm receiving are as follows, even after attempting to exclude the problematic module in the tsconfig.json file. Can an ...

Angular2's use of promises, observables, and Dependency Injection (

If I have a service that looks like this import {Injectable} from 'angular2/core'; @Injectable() export class MyService { search(oSrchParams){ let promise = () => new Promise((resolve, reject) => Meteor.call('mockSe ...

Is there a way for a function to be executed without being detected by surveillance?

Here's the Component I'm working with: @Component({ selector: 'app-signup', templateUrl: './signup.component.html', styleUrls: ['./signup.component.scss'] }) export class SignUpComponent implements OnInit ...