Jasmine has detected an undefined dependency

Testing out the following code:

   constructor(drawingService: DrawingService) {
       super(drawingService);
       //...
    }

   private writeOnCanvas(): void {
      this.drawingService.clearCanvas(this.drawingService.previewCtx);

      this.drawingService.baseCtx.fillStyle = 'red';
      this.drawingService.baseCtx.font = 'arial 20px';
      this.drawingService.baseCtx.textAlign = 'center';

      this.drawingService.baseCtx.fillText("hello",0, 0);
}

Introducing the DrawingService:

export class DrawingService {
   baseCtx: CanvasRenderingContext2D;
   previewCtx: CanvasRenderingContext2D;
   cursorCtx: CanvasRenderingContext2D;
   canvas: HTMLCanvasElement;
   previewCanvas: HTMLCanvasElement;

   clearCanvas(context: CanvasRenderingContext2D): void {
       //do something
   }

This is my .spec file:

fdescribe('TextService', () => {
  let service: TextService;
  let drawingServiceSpy: jasmine.SpyObj<DrawingService>;
  // const drawingServiceMock = {
  //   clearCanvas: jasmine.createSpy('clearCanvas'),
  //   baseCtx : CanvasRenderingContext2D,

beforeEach(() => {
  TestBed.configureTestingModule({
    providers: [ 
       { provide: DrawingService, useValue: drawingServiceSpy },
    ]
  });
  drawingServiceSpy = jasmine.createSpyObj('DrawingService',['clearCanvas']);
  service = TestBed.inject(TextService);
});


it('shoud write on baseCtx', () => {
  const ctx = CanvasType.baseCtx;
  service['drawingService'].baseCtx.fillStyle = 'red';
  service['drawingService'].baseCtx.font = 'Bold 10px Arial';
  service['drawingService'].baseCtx.textAlign = 'center' as CanvasTextAlign;

  service['writeOnCanvas'](ctx);

  expect(drawingServiceSpy.clearCanvas).toHaveBeenCalled();
  expect(drawingServiceSpy.baseCtx.fillText).toHaveBeenCalled();
});

The error message received is:

Cannot set property 'fillStyle' of undefined' error.

The issue may be related to:

{
  provide: DrawingService,
  useValue: drawingServiceSpy
}

Attempts were made using a mockClass but encountered errors...

Answer №1

Your order appears to be incorrect.

Here is a revised approach:

beforeEach(() => {
  // Start by creating the spy object for DrawingService
  drawingServiceSpy = jasmine.createSpyObj('DrawingService',['clearCanvas']);
  TestBed.configureTestingModule({
    providers: [ 
       { provide: DrawingService, useValue: drawingServiceSpy },
    ]
  });
  service = TestBed.inject(TextService);
});

For the test, make sure to set baseCtx as an empty object before proceeding further.

it('should write on baseCtx', () => {
  // Set baseCtx to an empty object first before assigning any properties to it
  service['drawingService'].baseCtx = {};
  service['drawingService'].baseCtx.fillStyle = 'red';
  service['drawingService'].baseCtx.font = 'Bold 10px Arial';
  service['drawingService'].baseCtx.textAlign = 'center' as CanvasTextAlign;

  service['writeOnCanvas'](ctx);

  expect(drawingServiceSpy.clearCanvas).toHaveBeenCalled();
  expect(drawingServiceSpy.baseCtx.fillText).toHaveBeenCalled();
});

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

Unexpected behavior: Angular post request does not include the expected request body

Embarking on my initial solo Angular project... I am endeavoring to make a post request to my freshly created web service and have implemented the following code: headers = new HttpHeaders( {'Content-Type':'text/plain'} ); l ...

Encountering problem with ngx material timepicker field within a mat dialog

When utilizing the ngx material timepicker field in a mat dialog, I am encountering an issue where the data is correctly mapped to the form group and the time displays properly when opening the clock view. However, the time does not display correctly on th ...

Having trouble with Angular 2 and localhost/null error while attempting to make an http.get request?

In my Angular 2 webpage, I am using the OnInit function to execute a method that looks like this (with generic names used): getAllObjects(): Promise<object[]>{ return this.http.get(this.getAllObjectsUrl).toPromise().then(response => response. ...

Assign a dynamic class to an element within an ngFor iteration

I am working with a template that includes an app-subscriber component being iterated over using *ngFor: <app-subscriber *ngFor="let stream of streams" [stream]="stream" [session]="session" (speakEvents)='onSpeakEvent($event)'> ...

Error encountered while running "ionic cordova run android" command

Recently, I revisited my Ionic Cordova app after a few months and encountered an unexpected dependency issue when attempting to make a minor adjustment to the app. Although the app previously functioned correctly, even reverting all changes failed to addre ...

Why does TypeScript keep throwing the "No inputs were found in the config file" error at me?

Why am I receiving the No inputs were found in config file error from TypeScript? I have set up my tsconfig.json in VS Code, but the error occurs when I try to build it. The terminal displays: error TS18003: No inputs were found in config file '/Use ...

In Typescript, convert an object into a different type while maintaining its keys in the resulting type

Imagine you have a code snippet like this type ResourceDecorator = (input: UserResourceDefinition) => DecoratedResourceDefinition const decorate: ResourceDecorator = ... const resources = decorate({ Book1: { resourceName: 'my-book', ...

A specialized HTTP interceptor designed for individual APIs

Hey there, I am currently working with 3 different APIs that require unique auth tokens for authentication. My goal is to set up 3 separate HTTP interceptors, one for each API. While I'm familiar with creating a generic httpInterceptor for the entire ...

Testing a Django Form with Multiple Submit Buttons for Maximum Functionality

Currently, I am in the process of writing unit tests for a webpage that utilizes multiple Submit buttons to manage the logical flow within my Django application. However, I'm facing an issue where I can't seem to retrieve the submit values in th ...

Effectively managing user access by authorizing levels and securing routes

Below is the code snippet for a protected route where the authentication status is managed by Redux. If there is no token saved in local storage, the isAuthenticated state is set to false. This code snippet is for protecting routes: import PropTypes from & ...

`How can I stop typescript from converting dynamic imports to require()?`

Currently, I am in the process of creating a Discord bot using discord.js. Interestingly, discord.js does not seem to be compatible with ESM modules, which has been causing some complications in my project. As a result, I have resorted to utilizing CommonJ ...

Insert data into Typeorm even if it already exists

Currently, I am employing a node.js backend in conjunction with nest.js and typeorm for my database operations. My goal is to retrieve a JSON containing a list of objects that I intend to store in a mySQL database. This database undergoes daily updates, bu ...

Error: Class cannot be loaded by React Webpack loader

I'm encountering an issue with my two typescript packages - a React application and an infrastructure package. The React app has a dependency on the infrastructure package (currently linked via npm). After adding a new class to the infrastructure pack ...

Is it possible to customize the default typography settings for Textfields and other components using a theme in Material UI v5?

Is there a method to customize the default typography for TextField and all inputs using themes? I am aware of this approach: components: { MuiInput: { styleOverrides: { root: { fontSize: '16px', ...

Is there a way to cancel or undo a transaction in the middle of using the PayPal JavaScript SDK?

As a newcomer to Angular, I am working on integrating PayPal as a payment gateway. However, I am unsure of the correct procedure to follow. paypal .Buttons({ createOrder: (data, actions) => { return actions.order.create({ purchase_ ...

Tips for simulating Axios requests in Jest

During my development process, I have implemented a function in my client/index.js file that utilizes axios to make HTTP requests import axios from "axios"; const createRequest = async (url, method) => { const response = await axios({ ...

Starting a line series from the beginning of the y-axis on a bar chart using chart.js

We have a new request from the business regarding the implementation of chart.js. Take a look at the image below, which shows a combination of bar and line charts. The line chart contains only a few data points. https://i.sstatic.net/mCSlR.png Within th ...

The number in Typescript should fall between 0 and 1, inclusive

Is there a method in Typescript that guarantees the value of a number will be less than or greater than a certain threshold? Currently, it permits the specification of a range of values, but I'm unsure about comparison. This is similar to what I have ...

VS Code fails to identify Typescript internal modules

I am currently facing issues with separating my TypeScript classes into distinct files using internal modules. Unfortunately, the main.ts file is not loading or recognizing the sub-modules. main.ts /// <reference path="Car.ts" /> module Vehicles { ...

Creating Versatile Functions for HttpClient Wrapping

Scenario: In my set of services, I find myself repeatedly writing code for data calls which results in a lot of duplicated code. To streamline the process and reduce redundancy, I am looking to implement a wrapper function: All these functions essentiall ...