Testing Angular 2 components with material icons and images

Recently, I finished creating a unique component that showcases an image, material icons, and a custom directive known as ticker. This directive allows for scrolling text if it exceeds the width of the element.

https://i.stack.imgur.com/GpDSr.png

My next challenge involved delving into unit testing using karma within angular cli/webpack. While most of the setup is clear to me, I've hit a roadblock in configuring images, material icons, and getting the HostListener directive to function properly.

This is what I have managed to piece together until now:

https://i.stack.imgur.com/9lC01.png

/* Configuration */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { TickerDirective } from '../../directives/ticker.directive';
import { MdIconModule, MaterialModule } from '@angular/material';
import { MdIconRegistry } from '@angular/material/icon';

/* Custom Components & Services */
import { FoodListComponent } from './food-list.component';
import { FoodDataService } from '../../services/food-items/food-data.service';
import { FoodItem } from '../../diet/food-item';
import { WorkingData } from '../../services/working-data/working-data';
import { WorkingDataService } from '../../services/working-data/working-data.service';

describe('FoodListComponent', () => {
  let component:          FoodListComponent;
  let fixture:            ComponentFixture<FoodListComponent>;
  let foodDataService:    FoodItem[];
  let workingDataService: WorkingData;
  let de:                 DebugElement[];
  let el:                 HTMLElement;

  /* Stubbed Service Data */
  let foodDataServiceStub = [{
    name: 'test food name ..................', // Test long name triggering ticker directive
    img: './no_image.png',
    description: 'test food description'
  }];

  let workingDataServiceStub = {
    today: new Date(),
    selectedDate: new Date(2016, 2, 5),
    targetDate: new Date(2016, 2, 7),
    data: {exercise: 'Squat'}
  };

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      declarations: [ FoodListComponent, TickerDirective ],
      imports: [ MaterialModule.forRoot(), MdIconModule], // Unsure about correctness
      providers: [
        { provide: FoodDataService, useValue: foodDataServiceStub },
        { provide: WorkingDataService, useValue: workingDataServiceStub } ,
        MdIconRegistry // Uncertain about correctness
      ],
      schemas: [ NO_ERRORS_SCHEMA ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(FoodListComponent);
    component = fixture.componentInstance;

    /* Inject services */
    foodDataService = TestBed.get(FoodDataService);
    workingDataService = TestBed.get(WorkingDataService);

    /* Assign Services */
    component.workingData = workingDataService;
    component.foods = foodDataService;

    fixture.detectChanges();
    de = fixture.debugElement.queryAll(By.css('span'));
    el = de[0].nativeElement;
    // console.log(el);
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
  it('should have the correct food name', () => {
    expect(el.textContent).toContain('test food name ..................');
  });
});

Image: In the same directory as the spec.ts file, there is a png named 'no_image.png'. The framework identifies the image without any 404 errors, yet it fails to render.

Ticker Directive: The span associated with the ticker seems correctly set up, but the HostListener isn't responding to mouseover events as expected. I attempted importing HostListener into TestBed, which resulted in an error.

Material Icons: Although the ligatures of the material icons are visible, they do not render on the screen. Research suggested importing Http, but this led to another error.

I would greatly appreciate assistance in implementing these features, along with guidance on troubleshooting similar issues in the future (my attempts at finding solutions via search engines proved fruitless).

Answer №1

The component does not require high-level logic, making it difficult to write extensive unit tests. Instead, integration testing is recommended for testing the value, color, and size of the component.

INTEGRATION TESTING involves combining individual units and testing them as a group to identify faults in their interaction. Test drivers and test stubs play important roles in Integration Testing.

Learn more about Integration Testing

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

Exploring the Depths of Observables in Angular2 Guards

I have a Guardian overseeing a specific route. Within the canActivate method, I am trying to perform two HTTP requests, with the second request being dependent on the response of the first one. However, it seems like the second request is not being trigger ...

TypeScript is throwing an error because a value has been declared but never actually used in the

private tree_widget: ITreeWidget; private $ghost: JQuery | null; private drag_element: DragElement | null; private previous_ghost: IDropHint | null; private open_folder_timer: number | null; constructor(tree_widget: ITreeWidget) { this.tree_widget = t ...

When a URL is triggered via a browser notification in Angular 2, the target component ceases to function properly

Whenever I access a URL by clicking on a browser notification, the functionality of the page seems to stop working. To demonstrate this issue, I have a small project available here: https://github.com/bdwbdv/quickstart Expected behavior: after starting t ...

Utilizing Angular to lazily load multiple routes/paths within a single module

I am currently in the process of setting up multiple horizontal routes (not nested) and grouping them into one lazy-loaded module. However, I am facing a challenge trying to properly match these routes within the lazy-loaded feature module itself. Below ...

Is there a way to ensure that fields in a sub component are validated whenever we attempt to switch the Tab using a route

Hi there, I could really use your assistance. I've done some research, but I haven't been able to find a suitable solution for my problem. I have this shared component that contains the following code which enables tab navigation through various ...

How to Build a Number Spinner Using Angular Material?

Is there a number spinner in Angular Material? I attempted to use the code provided in this question's demo: <mat-form-field> <input type="number" class="form-control" matInput name="valu ...

Tips on assigning array union as the return type of a function

I am working with a function parameter that accepts an array union, like this: (ClassA|ClassB)[]. How can I return either ClassA[] or ClassB[] from the function? When attempting to return type (ClassA|ClassB)[], I encounter the following error: Assig ...

Why does isDisplayed method in Protractor return "No element found using locator" instead of a boolean value?

In my code, I've created a function called isElementDisplayed which features a call to element.isDisplayed. I'm curious as to why the isDisplayed method sometimes returns No element found instead of a boolean value. isElementDisplayed(element: ...

Drag and drop functionality in Angular 2 using TypeScript

Has anyone experimented with the drag and drop functionality using Angular2 RC with TypeScript? Thanks, Sanket ...

Is it possible to use AngularJS promise scheduling with `async`/`await` syntax?

When working with AngularJS services, TypeScript often recommends that I switch my code to use async/await functions. While I understand that using the await keyword is compatible with third-party promises because it essentially translates to calling then ...

Can you show me a way to display a dynamically created array component on an Angular2 template html?

One way I've been able to generate dynamic component instances is by choosing from pre-existing components. For instance, @Component({ selector: 'dynamic-component', template: `<div #container><ng-content></ng-conten ...

Ways to substitute a null value in ngFor

When the item value is null, an error occurs in the console and the functionality stops working. How can I verify or replace the null value with my own preferences? this.xx = this.broadCastService.events.subscribe((line: Line) => { this.configService ...

"Upon invoking the services provider in Ionic 2, an unexpected undefined value was

I encountered an issue while setting a value in the constructor of my page's constructor class. I made a call to the provider to fetch data. Within the service call, I was able to retrieve the data successfully. However, when I tried to access my vari ...

Navigating with AngularJS 2 on Internet Information Services (IIS)

I'm facing an issue with my ASP.NET CORE application that uses angular2 routing. While running the app locally, the routes resolve correctly. However, when I deploy it to a server (running on IIS 7), the routes seem to be appending the folder director ...

Ways to interpret and fix a conflict in npm dependency and understand the output

I'm encountering some issues while attempting to set up my project. The errors I'm running into during the installation process are: npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: @angular-devkit/< ...

Navigating to Angular components within a statically hosted S3 application

I am in the process of creating an application using Angular4 on the frontend. The main objective for deployment is to serve the frontend as static content from an AWS S3 bucket. Everything seems to be working smoothly except for one crucial issue. When u ...

Typescript - Creating a Class with Constructor that Extends an Interface without Constructor

I am faced with an interface structured as follows: interface Person { id: number name: string } In my implementation class for this interface, I have the following code: class PersonClass implements Person { id: number = 123 name: string = &apo ...

Is there a way to incorporate my getter into a computed property?

My Vuex Store is built using Vuex module decorators and I am facing an issue with using a getter for a computed property. Here is my code: @Module export default class WorkoutModule extends VuexModule { _workout: Workout; @Mutation startWork ...

The age-old debate: Ngxs or Behavior Subject, which one should you go

I'm embarking on creating an admin panel for a Payment gateway product using Angular's latest version, working with a multitude of microservices. With experience in NGXS state management, as well as subjects and behavior subjects, I'm undeci ...

Exploring the world of publishing Angular 2 applications

I recently created an Angular 2 application using npm, but as a beginner I am unsure of some aspects. For instance, when I publish my application, I typically use npm publish to share it on my npm account online. However, I am wondering if there is a way t ...