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

GraphQL query result does not contain the specified property

Utilizing a GraphQL query in my React component to fetch data looks like this: const { data, error, loading } = useGetEmployeeQuery({ variables: { id: "a34c0d11-f51d-4a9b-ac7fd-bfb7cbffa" } }); When attempting to destructure the data, an error ...

Angular - Turn off date selection in datepicker when toggle switch is activated

I am currently utilizing angular material and I need to figure out how to deactivate the datepicker after toggling a slide. Below is my upload form equipped with a datepicker: <form #uploadForm="ngForm" (keydown.enter)="$event.preventDefault()" (ngSub ...

If you're trying to work with this file type, you might require a suitable loader. Make sure you

Attempting to utilize Typescript typings for the Youtube Data API found at: https://github.com/Bolisov/typings-gapi/tree/master/gapi.client.youtube-v3 Within the Ionic framework, an error is encountered after running 'Ionic Serve' with the follo ...

Adding existing tags to Select2 in Angular2 can be accomplished by following these steps:

HTML: <select data-placeholder="Skill List" style="width:100%;" class="chzn-select form-control" multiple="multiple"> <option *ngFor="#skill of allSkills" [ngValue]="skill">{{skill}} </option> </select> TS: allSkills = [& ...

Need to monitor a Firebase table for any updates

How can I ensure my Angular 2 app listens to changes in a Firebase table? I am using Angular2, Firebase, and TypeScript, but the listener is not firing when the database table is updated. I want the listener to always trigger whenever there are updates or ...

Proper utilization of ngIf in conjunction with mat-cell

I am attempting to show a specific value only if the item possesses a certain property, but I keep seeing [object Object] instead. Here is my current method: <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDe ...

Angular 8 combined with Mmenu light JS

Looking for guidance on integrating the Mmenu light JS plugin into an Angular 8 project. Wondering where to incorporate the 'mmenu-light.js' code. Any insights or advice would be greatly appreciated. Thank you! ...

Assign a value to a variable using a function in Typescript

Is there a way in typescript to explicitly indicate that a function is responsible for assigning value to a variable? UPDATED CODE Here, the code has been simplified. While getText() ensures that it will never be undefined, this may not hold true in subs ...

Angular Form Validation: Ensuring Data Accuracy

Utilizing angular reactive form to create distance input fields with two boxes labeled as From and To. HTML: <form [formGroup]="form"> <button (click)="addRow()">Add</button> <div formArrayName="distance"> <div *n ...

What causes the component's constructor to be invoked multiple times instead of being efficiently reused by the router?

I came across this interesting article where the writer discusses how the router reuses components to avoid unnecessary DOM modifications: In order to prevent unnecessary changes to the DOM, the router will reuse components when the parameters of the co ...

Certain Material-UI components appear to lack proper styling

I found a tutorial on how to incorporate material UI into my app at this link: https://mui.com/material-ui/getting-started However, I noticed that some components are not styled as expected and customizing the theme seems to have no effect... This is how ...

Exploring how to utilize element.find() with class names in Angular's unit testing

Every time I run this test, I encounter the error Expected undefined to be true. it('needs to verify correct classes', function() { // doesn't give desired output expect(element.find('.exampleClass').hasClass('ng-hide&a ...

Is it possible for an Angular2 HTTP request to retrieve the response body as binary data?

I'm facing an issue with a URL that returns HTML content with charset=iso-8859-7. Angular's HTTP request converts the data to utf8 by default, making it difficult for me to encode them back in iso-8859-7 properly. Upon researching, I discovered t ...

Unable to send event from JavaScript to Component in Ionic

My goal is to notify a component that a script file has finished loading. My approach involves using the onload event of an element to dispatch an event. A service will then register an event listener for this event, waiting for clients to subscribe to an ...

Generating Dynamic HTML Tables From JSON Data in Angular

Is it possible to generate a dynamic HTML table based on JSON data containing column and row information? { "columnNames": [ "Applicant ID(id|Optional)", "Roll No", "Applicant Name", "Password", "CA ID", ...

The html-duration-picker is not being displayed in the proper format

I've been working on integrating an external library that allows for inputting document length. Specifically, I'm using the html-duration-picker library, but it seems like the input functionality is not quite right for durations. Could it be th ...

Creating and handling Observable of Observables in RxJS: Best practices

Within my Angular application, there are multiple services that have dependencies on each other. To manage this, I have created a dependency map as shown in the example below: let accountInitialization$: Observable<void>; let productInitialization$: ...

Utilizing Typescript Decorators to dynamically assign instance fields within a class for internal use

I am interested in delving into Typescript Decorators to enhance my coding skills. My primary objective is to emulate the functionality of @Slf4J from Project Lombok in Java using Typescript. The concept involves annotating/decorating a class with somethin ...

Converting a Typescript project into a Node package: A step-by-step guide

I'm currently dealing with an older typescript project that has numerous functions and interfaces spread out across multiple files. Other packages that depend on these exports are directly linked to the file in the directory. My goal is to transition ...

Is it necessary to only override the monospaced font?

Can the monospace font in Angular Material be customized for just the <code>foo</code> blocks? I want to use a font where the number zero 0 looks distinct from the letter oh O. ...