Testing a reusable component in Angular using unit testing techniques

Currently, I am creating a test for an AppleComponent which has the following type:

<T,U extends BananaComponent<T>>
. This component also contains BananaComponent<T>.

Target Component

export class AppleComponent<T,U extends BananaComponent<T>>{
   public appleA = 'appleA';
   public appleB = 'appleB';
   public appleC !: U;

}

Extended Component

export abstract class BananaComponent<T> implements OnInit{
   public bananaA = 'bananaA';
   public bananaB = 'bananaB';
}

In this case, my spec file is used to perform testing on the AppleComponent.

import { CommonModule } from '@angular/common';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import {AppleComponent} from '....';
import {BananaComponent} from '....';

describe('AppleComponent', () => {
   let component: AppleComponent;
   let fixture: ComponentFixture<AppleComponent>;

   beforeEach(()=>{
     TestBed.configureTestingModule({
         declarations:[AppleComponent],
         imports:[BananaComponent],
     });
     fixture = TestBed.createComponent(AppleComponent);
     component = fixture.componentInstance;
   });

   it('should have default values',() => {
      expect(component.appleA).toBe('appleA','appleA has appleA as default value'); // this will pass
   });
});

However, I encountered an issue with the spec file not being compilable.

After examining the logic, I realized that the types of the component and fixture were incorrect. To address this, I made some modifications as detailed below:

// Initially, define a random type within the test and assign it to AppleComponent and BananaComponent.

type typeA = { };  
type typeModel = AppleComponent<typeA, BananaComponent<typeA>>;   

let component: typeModel; 
let fixture: ComponentFixture<typeModel>

Answer №1

Have you attempted specifying the type of your component when creating it?

fixture = TestBed.createComponent<AppleComponent<TestObject>>(AppleComponent)

You may need to create a separate TestObject Model that is not compatible with generic Type T.

export class TestObject {

}

Answer №2

One aspect of this concept that tripped me up is:

AppleComponent does not directly inherit from BananaComponent, so component. cannot access properties or methods from BananaComponent.

Essentially, what's happening here is the type of AppleComponent is related to BananaComponent; The goal is to ensure that the input types in AppleComponent match those in BananaComponent.

Therefore, when testing, it is crucial to set up the component and fixture correctly.

Solution to my initial question

// Start by defining a random type within the test, then apply it to both AppleComponent and BananaComponent.

type typeA = { };  
type typeModel = AppleComponent<typeA, BananaComponent<typeA>>;   

let component: typeModel; 
let fixture: ComponentFixture<typeModel>

To better understand how the types of AppleComponent and BananaComponent interact, refer to the detailed code snippets below.

AppleComponent

export class AppleComponent<T,U extends BananaComponent<T>>{
   public appleA = 'appleA';
   public appleB = 'appleB';
   public applePurchase !: U;
}

BananaComponent

export abstract class BananaComponent<T> implements OnInit{
   public bananaA = 'bananaA';
   public bananaB = 'bananaB';
   public bananaPurchase : T;

   public totalPurchase: T;
}

The above code reveals that:

  1. In BananaComponent, type T ensures that the input value bananaPurchase matches the type of totalPurchase. For example, if bananaPurchase = 1000 (a number), then totalPurchase must also be a number.

  2. This same relationship exists in AppleComponent due to its extension of BananaComponent, indicating that applePurchase should have the same type as bananaPurchase and totalPurchase.

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

How to Use Hyperledger Composer's Rest-Server-Api Local-Passport Strategy in an Angular Application without Node.js

Is it possible for me to implement the passport-local strategy in my project, considering that I am using an angular front-end generated by the composer-rest-server tool? I noticed in the documentation for passportjs regarding passport-local, it mentions ...

Is it possible to assign a string literal type as a key in TypeScript mappings?

Is it possible to map a string literal type as a key in a new type? I attempted this, but it did not work as expected. const obj = { type: "key", actions: { a() {}, b() {}, }, } as const; /* Map to { key: { a() {}, b() {}, } */ t ...

Issue: Module 'stylelint' not found in Angular Project

I've been attempting to execute this command to validate all of the .scss files (and even tried with .css files) and I keep encountering this error. $ stylelint "apps/**/*.scss" It worked once before but not anymore, even after restarting my compute ...

I aim to display interconnected information from various APIs in a cohesive manner

I am working with two APIs: component.ts ngOnInit(): void { this.getQueryCountriesList().subscribe(arg => { this.countryDatas = arg; }); this.getQueryNights().subscribe(obj => { this.nightDatas = obj; }); ...

What could be causing the issue with "class not being recognized as a constructor" error that I am encountering?

When attempting to create an instance from modules in routing, I consistently encountered the error message "class is not a constructor." Below is the code snippet: export class Modules{ modules : object = { masterdata : MasterdataModule, shop : ...

Refresh Angular page data following new routing paths

The chat box page in the image below was created using Nebular: Nebular Documentation View Chat Box Photo After clicking on one of the user names (2) from the list, the URL ID (1) changes but the corresponding data does not load. Note: I have created a m ...

Using PHP encryption and decrypting with AES in Angular using Crypto-JS

I have successfully implemented encryption and decryption in PHP using aes-256-cbc. However, I am now facing a challenge in decrypting the same content in Angular 7. Encryption in php using aes-256-cbc by following method $this->data ="plaintext&qu ...

How Keyof can render an object undefined and prevent accurate verification

Encountering TS2532 error: Object is possibly 'undefined' while attempting to access an object's value by dynamically selecting the key. TypeScript seems to be restricting me from checking the field values, and I'm unsure of the underly ...

Make sure to wait for the observable to provide a value before proceeding with any operations involving the variable

Issue with handling observables: someObservable$.subscribe(response => this.ref = response); if (this.ref) { // do something with this.ref value } ERROR: this.ref is undefined How can I ensure that the code relying on this.ref only runs after ...

"An approach to testing and logging multiple times in Python with the help of -nosetest and unittest

Here is a condensed version of the issue: a = [[1,2,3][0,0,0]] b = [[1,0,1][0,0,0]] c = [[0,0,0][1,0,1]] If level 1 is [] and level 2 is [[]], my goal is to compare every list to see if their level 2's match (disregarding order). In this example, b ...

Divide a string using multiple delimiters just one time

Having trouble splitting a string with various delimiters just once? It can be tricky! For instance: test/date-2020-02-10Xinfo My goal is to create an array like this: [test,Date,2020-02-10,info] I've experimented with different approaches, such ...

How can a child component class in Angular 2 be initialized when extending a parent class?

Let's consider a scenario where we have a component called ChildComponent that extends from the Parent class. How do we go about initializing the ChildComponent class? In Angular 2, when this component is used in HTML, it automatically invokes the Chi ...

Display Angular code and HTML within an Angular webpage without it being rendered

Displaying Angular code and HTML examples on my Angular page is proving to be challenging. No matter what I try, Angular keeps trying to parse it. I attempted using <code>, <pre>, and even this: &lt;div class="name">&#123;&#123; ...

Obtain the selected type from a tuple after filtering

I have a tuple with multiple objects stored in it. const repos = [ { name: 'react', type: 'JS' }, { name: 'angular', type: 'TS' }, ] as const const RepoTypes = typeof repos const jsRepoTypes = FilterRepos<&a ...

Continue looping in Javascript until an empty array is identified

Currently, I am in search of a solution to create a loop in Javascript that continues until the array of objects is empty. The object I am working with looks like this: "chain": { "evolves_to": [{ "evolves_to": [{ ...

Ways to invoke a component function from another component

Hello all, I am currently learning Angular and I have encountered an issue where I need to call a function from one component in another component. Most of the solutions I found online involve scenarios where the components are either child or sibling comp ...

A guide on automatically focusing on a Material UI Formik form TextField using React and TypeScript

I'm attempting to automatically focus my textField, but the 'autoFocus' attribute only seems to work after I submit the form and add a value. If no values are added (i.e. when opening the miui modal for the first time), the autoFocus does no ...

Tips for replacing global functions during unit testing using Jest

Currently, I am in the process of creating unit tests for a module and could use some assistance with managing global variables and functions. Allow me to explain my query below: Imagine the module I wish to test is named 'needTest.js' and is st ...

Cyrillic characters cannot be shown on vertices within Reagraph

I am currently developing a React application that involves displaying data on a graph. However, I have encountered an issue where Russian characters are not being displayed correctly on the nodes. I attempted to solve this by linking fonts using labelFont ...

Angular 6 form controls with reactive elements

Looking to create a simple homepage using Angular 6. One of the features will include tests for prime factorization and leap years, implemented with reactive forms for validation. However, I am facing an issue where I cannot execute both functions simultan ...