Creating a component with @input for unit tests in Angular can be achieved through the following steps

I'm encountering issues while attempting to create a testing component with an @input. The component utilizes properties from the feedback model, and although I imported them into the test file, errors are being displayed. Can anyone offer assistance?

feedback-card.component.ts

import { Component, OnInit, Input, HostBinding } from '@angular/core';
import { FeedbackCommentsComponent } from '../feedback-comments/feedback-comments.component';
import { routerAnimation } from '../../../../utils/page.animation';
import { AuthService } from '../../../../services/auth.service';
import { Feedback } from '../../../../models/feedback';
import { FirestoreService } from '../../../../services/firestore.service';
import * as firebase from 'firebase/app';
import 'firebase/firestore';
import { first } from 'rxjs/operators';
import { MatBottomSheet } from '@angular/material/bottom-sheet';
import { MatSnackBar } from '@angular/material/snack-bar';

@Component({
  selector: 'app-feedback-card',
  templateUrl: './feedback-card.component.html',
  styleUrls: ['./feedback-card.component.scss'],
  animations: [routerAnimation]
})

export class FeedbackCardComponent implements OnInit {

  @HostBinding('@routerAnimation') routerAnimation = true;
  @Input() feedback: Feedback
  @Input() isAdmin = false
  input
  userId
...

feedback-card.component.spec.ts

import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MatBottomSheet } from '@angular/material/bottom-sheet';
import { MatSnackBar } from '@angular/material/snack-bar';
import { FirestoreService } from '../../../../services/firestore.service';
import { AuthService } from '../../../../services/auth.service';
import { FeedbackCardComponent } from './feedback-card.component';
import { CommonModule } from '@angular/common';
import { Feedback } from '../../../../models/feedback';
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppModule } from 'src/app/app.module';
import { MatDialogModule } from '@angular/material/dialog';
import { TranslateFakeLoader, TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/compiler';
import { FunctionsService } from 'src/app/services/functions.service';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { Skill } from 'src/app/models/skill';

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

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
        imports: [
          CommonModule,
          ReactiveFormsModule,
          FormsModule,
          AppModule,
          MatDialogModule,
          TranslateModule.forRoot({
              loader: {
                provide: TranslateLoader,
                useClass: TranslateFakeLoader
              }
          })
      ],
      schemas: [
        CUSTOM_ELEMENTS_SCHEMA
      ],
      declarations: [ 
        FeedbackCardComponent,
      ],
      providers: [
        FirestoreService
        MatSnackBar,
        MatProgressBarModule,
        FirestoreService,
        FunctionsService,
        TranslateService,
    ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(FeedbackCardComponent);
    fireStoreServiceMock = TestBed.inject(FirestoreService);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

Error Log:

TypeError: Cannot read property 'skill' of undefined
TypeError: Cannot read property 'skill' of undefined
    at FeedbackCardComponent_Template (ng:///FeedbackCardComponent.js:305:52)
    at executeTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9545:1)
    at refreshView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9414:1)
    at refreshComponent (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10580:1)
    at refreshChildComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9211:1)
    at refreshView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9464:1)
    at renderComponentOrTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9528:1)
    at tickRootContext (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10754:1)
    at detectChangesInRootView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10779:1)
    at RootViewRef.detectChanges (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:22792:1)

Answer №1

When using fixture.detectChanges(), remember that it triggers the calling of ngOnInit. Therefore, ensure that your inputs are defined beforehand.

You can follow this approach:

beforeEach(() => {
    fixture = TestBed.createComponent(FeedbackCardComponent);
    fireStoreServiceMock = TestBed.inject(FirestoreService);
    component = fixture.componentInstance;
    component.feedback = // create a mock for feedback
    component.isAdmin = // set to false by default, but you may want to mock it here as well.
    fixture.detectChanges();
  });

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

Angular2: Leveraging click events to manage CSS classes on elements

I am currently developing a web app using Angular 2. I'm facing an issue where the active element should receive an extra CSS class when clicked, but adding the ":active" CSS attribute with a custom class doesn't work as expected. The ":focus" pr ...

Leverage Springs with TypeScript

function createDefaultOrder(items: any[]): number[] { return items.map((_, index) => index); } type CustomHandler<T> = (index: number) => T; type CustomValues = { zIndex: number, y: number, scale: number, shadow: number, immediate: ...

What is the best way to pass an array of 8-digit strings from an input in Angular to a Node.js backend?

I am currently facing a challenge where I need to pass an array of 8 digit strings from an Angular input to a Node.js endpoint. The method below works perfectly fine when passing a single string, but how can I handle an array of 8 digit strings as input? ...

Failure to set X-XSRF-TOKEN header in Angular5

After exploring several solutions, I have yet to find one that works for me. This issue on Github closely mirrors my problem (https://github.com/angular/angular/issues/20511) My setup includes Angular 5.2.5, Chrome Version 65.0.3325.146, and Spring Boot ...

Error: Could not locate application for Ionic Serve command

I have been developing a project in Ionic2 on another computer. However, when I try to run ionic serve on my PC, an error message appears: 192.168.1.100:8100 Application not found I have configured my app to use a static IP address... How can I resolve ...

Encountering a 404 error with systemjs-angular-loader.js in a production environment

Currently, I am working on the most recent Angular/Quickstart project that utilizes systemjs-angular-loader.js to load app-relative HTML templates without the need for the moduleId property. During development and testing with "npm start" to serve pages, ...

Error encountered while parsing an Ionic template involving Ionic select, npm, and different versions of Ionic

I keep encountering the error message: ion-select-option' is not a known element. Here's what works: <ion-item> <ion-label>Gender</ion-label> <ion-select placeholder="Select One"> <ion-option value="f" ...

Sources of the TypeScript library in WebStorm

I'm brand new to TypeScript. I decided to use WebStorm because I'm familiar with JetBrains tools. In other programming languages, I'm used to having a workflow that includes some kind of dependency management system like Maven, which allows ...

Can you explain the process of retrieving data from a Material 2 table?

In my Angular 2 application, I am utilizing a Material 2 table to showcase items and their corresponding data. Each row in the table has an edit button on the right side, which triggers the appearance of input fields populated with the values of that speci ...

"Customizing the properties of an Angular Material mat-slide-toggle: A step-by-step

<mat-slide-toggle>Slide Me!</mat-slide-toggle> https://i.stack.imgur.com/p1hzD.png https://i.stack.imgur.com/aCzs1.png Is it possible to customize the toggle-thumb-icon to increase its length and position it at the end of the bar? ...

When attempting to select dates from the picker options, the array is found to be devoid of any entries

My challenge lies in working with an array of dates retrieved from the server to determine which dates should be disabled on the datepicker. getStaffAvailability(){ let x = this; this.$http.get(this.weeklyAvailabilityUrl + "GetAv ...

Issue detected in Angular 2 Heroes Tutorial: The element with the selector "my-app" was not found in the document

Currently, I am in the process of following along with the Heroes tutorial on the official angular website. The project was created using CLI and everything seemed to be working smoothly up until Part 6 on Routing: https://angular.io/tutorial/toh-pt5 In ...

Is it possible to concurrently hot module reload both the server (.NET Core) and client (Angular)?

Using the command 'dotnet watch run' to monitor changes in server code and 'ng build --watch' for Angular code updates has been successful. It rebuilds the code correctly into directories "bin/" and "wwwroot/" respectively. myapp.cspro ...

Ways to prevent the use of the JavaScript increment (++) or decrement (--)

I have created two functions for a multi-step configuration on a webpage. protected clickNext(event:any, config:any) : any{ this.activeIndex++; } protected clickPrev(event:any, config:any) : any{ this.activeIndex--; } Here are the buttons: < ...

Utilizing Typeface Styles in SCSS with the Latest Webpack Version 4

My Angular 6 SPA utilizes Webpack 4 for bundling, and I have encountered an issue while trying to import external fonts into the project. The project is based on the repository found at; AngularWebpackVisualStudio Example Repo After inspecting the webpac ...

Encountering a 404 error for core.js and browser.js while loading an Angular 2 app through system.src.js

I am new to Angular2 and have followed the Angular2 quickstart and tutorial to get started. Just to provide some context, when a user clicks on a link in the top navigation bar of my webapp, it triggers a server side request. The resulting page returned t ...

Angular 2 Form Error: Control Not Found

I'm facing an issue with Angular 2 Forms where adding more than one control seems to be getting ignored. Despite following numerous guides on how to properly implement this, none of the suggested methods seem to work in my case. In my template, I hav ...

How to Alter the Color of a Hyperlink in HTML

I've been working on an angular2 application and I'm using a hyperlink to trigger a method that opens a small popup window. I've tried different methods to change the color of the link when it's clicked, but so far none have worked. Th ...

Adjusting the Material UI Select handleChange function

const handleObjectChange = (event: React.ChangeEvent<{ value: unknown }>) => { const { options } = event.target as HTMLSelectElement; const selectedValues: object[] = []; for (let i = 0, l = options.length; i < l; i += 1) { if ...

Trigger an event in Angular 2 and send it to the main application component

I need to trigger an event from a component that serves as the starting point of my application. This particular component manages a websocket connection and I must send a message, hence the need to trigger this event. The bootstrap component only contain ...