Simulating dependencies of Angular 2 components during unit testing

Struggling with accessing mocked service methods in Angular 2 during component unit testing. Seeking guidance on a standard approach, despite following Angular docs closely. The challenge lies in reaching the mocked service's methods.

My immediate goal is to grant the component access to the mocked service's API and specifically spy on the login method to verify its invocation.

login.page.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { DBService } from '../../services/db/db.service';
import { TabsPage } from '../tabs/tabs.page';

@Component({
  templateUrl: 'login.page.html',
})
export class LoginPage {
  constructor(public navCtrl: NavController, public dbService: DBService) {}

  login() {
   this.dbService.login();
  }
}

db.service.mock.ts

export class MockDBService {

  public login(): string {
    return 'login service';
  }
}

login.page.spec.ts

import { LoginPage } from './login.page';
import { TestBed, inject, ComponentFixture } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NavController } from 'ionic-angular';
import { mockNavController } from 'ionic-angular/util/mock-providers';
import { DBService } from '../../services/db/db.service';
import { MockDBService } from '../../services/db/db.service.mock';

describe('Login Page:', () => {

  let fixture: ComponentFixture<LoginPage>;
  let component: LoginPage;
  let mockDBServiceInstance: MockDBService;

  beforeEach(() => {

    TestBed.configureTestingModule({
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      declarations: [
        LoginPage,
      ],
      providers: [
        {provide: NavController, useValue: mockNavController},
        {provide: DBService, useValue: MockDBService},
        LoginPage,
      ],
    });

    fixture = TestBed.createComponent(LoginPage);
    component = fixture.componentInstance;
    mockDBServiceInstance = TestBed.get(DBService);

  });

  describe('testing the login functionality', () => {
    it('should call the login method on the DBService', () => {
      spyOn(mockDBServiceInstance, 'login');
      component.login();
      expect(mockDBServiceInstance.login).toHaveBeenCalled();
    });
  });
});

An error occurs:

Error: <spyOn> : login() method does not exist

In my pursuit of a solution, I welcome any tips or best practices to address this issue effectively within the Angular framework.

Many thanks

Answer №1

In order to supply a simulated class, you must utilize the useClass method like so:

{provide: StorageService, useClass: MockStorageService}

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

What is the best way to execute multiple functions simultaneously in Angular?

Within a form creation component, I have multiple functions that need to be executed simultaneously. Each function corresponds to a dropdown field option such as gender, countries, and interests which are all fetched from the server. Currently, I call th ...

Ways to update the content of a NodeList

When I execute this code in the console: document.querySelectorAll("a.pointer[title='Average']") It fetches a collection of Averages, each with displayed text on the page: <a class="pointer" title="Average" onclick="showScoretab(this)"> ...

Passing a map from the SpringBoot backend to the Angular view and storing it in LocalStorage

I'm facing a challenge with this task. I am trying to transfer a Map from my Spring Boot backend to an Angular application. Controller @GetMapping("/dict") public Map<String, String> getAll(){ return dictionaryService.getAll(); } @ ...

Can the serialization of AJAX URL parameters in jQuery be customized?

Is there a way to instruct jQuery or an AJAX call on how to format query string parameters other than writing a custom serializer? I am using a jQuery AJAX call and passing an object with URL parameters var params = {name: 'somename', favColors ...

Troubleshooting: Bootstrap not functioning in Angular with Webpack due to vendor bundle issue

Bootstrap is included in my vendor.js bundle, as shown in the snapshot below, https://i.stack.imgur.com/q5k8c.png Upon inspecting the DOM, it's clear that bootstrap classes are being applied too, as seen in the snapshot below, https://i.stack.imgur. ...

Issue with font selection in Fabric.js

I am currently working with fabric js version 1.7.22 alongside angular 7 to create a text editor. I have encountered an issue when trying to add text to the canvas using a custom font as shown in the code snippet below. var canvas= new fabric.Canvas(&apos ...

AngularJS does not update values properly if there is a style applied to the parent container

I'm struggling to find the best approach to handle this situation. This is how my AngularJS code looks: <span class="something" ng-hide="onsomecondition"> {{value}} </span> .something{ text-align:left; padding:10px;} Issue: The value ...

Setting up ESM for Firebase functions: A step-by-step guide

Our server application needs to utilize the most recent ipfs-http-client as it is an authorized package for accessing IPFS. However, the project must switch to using ESM starting from v57.0.0. I have invested a significant amount of time into this and it h ...

Derive a data type from a parameter passed to a function defined within an interface

I am working with a function defined in an interface as shown below: interface UseAutocompleteReturnValue { ... getRootProps: (externalProps?: any) => React.HTMLAttributes<HTMLDivElement>; } Within my interface, I aim to create a prop named rootP ...

What is the process for defining the type of the context for an Apollo resolver?

I am facing an issue with my Apollo GraphQL subgraph where I need to define the type for the context argument in my resolvers. When creating a resolver, I tried setting the context type like this: interface Context { dataSources: { shopify: Shopify; ...

Incorporating Angular module into the mean.io bundle

Need help with adding the angular-ui-grid module to a mean.io package: $ cd packages/custom/mypackage $ npm install angular-ui-grid --save To import the JS, add this line to packages/custom/mypackage/public/index.js: import 'angular-ui-grid'; ...

Tips for displaying a notification about data filtering and loading using the Async Pipe in Angular

Can someone assist me with this issue? I have a code snippet that retrieves characters from an API and allows me to search for specific characters using input. I am trying to display different messages on my HTML page based on the search results. If no it ...

Deciding between a Component, Resolver, or Guard for redirecting authentication in Angular: Which middleware option is the

Incorporating an external authentication system into my Angular application is currently my focus, and I am determined to follow the most effective approach. The authentication process functions in such a way that upon successful authentication from a des ...

Utilizing JavaScript to exchange "unprocessed" Apple Events on OS X (El Capitan)

I'm exploring the new JavaScript Automation feature in OS X (10.11) to automate a specific application that lacks a dictionary. My current approach involves using AppleScript with raw Apple Events as follows: tell application "Bookends" return «ev ...

"Looking for a way to eliminate the background of an image on NextJS? Learn

https://i.stack.imgur.com/zAsrJ.png When this image is incorporated into a Nextjs rendering, it unexpectedly includes additional content. <div className="flex flex-col items-start justify-start rounded-3xl p-4 bg-boxi w-1/3"> <div cla ...

Adjusting the height of an IFRAME on the fly

One solution to dynamically fix the height issue of Google Trend charts is by modifying the code output. An example of this can be seen in the code snippet below: <iframe width="600" height="320" src="http://www.google.com/trends/fetchComponent?hl=en-U ...

How to retrieve an object within an object using a dynamic key in Vue JS?

Within my Vue JS 2.x project, I am utilizing a v-for loop to iterate over an array of objects. Each object in the array contains a dynamically named "key", which is unique to each object. My goal is to access the data associated with each key in order to d ...

Discover the Hassle-Free Approach to Triggering Angular Material Menu with ViewChild and MatMenuTrigger

Is there a way to programmatically open an Angular Material menu using a Template Reference Variable on a button trigger that is accessed in the component through ViewChild? I want the menu to open when the mouse hovers over it, instead of just clicking i ...

Final callback in async parallel operation fails to trigger

I am currently facing an issue with an async parallel block that is supposed to execute two queries in MongoDB. Despite having valid return results and no errors being reported during each step of the function(callback), I have encountered a problem wher ...

Can you identify the issue with my database file?

Here is the content from my database.js file: const MongoClient = require('mongodb').MongoClient; const db = function(){ return MongoClient.connect('mongodb://localhost:27017/users', (err, database) => { if (err) return co ...