Imitate a required component in a service

I am currently facing an issue with mocking a dependency in a service. I am not sure what is causing the problem. It's not the most ideal class to test, but I am mainly focused on code coverage. Below is the code for the service:

@Injectable()
export class SessionService {
    constructor(private sessionStore: UserStore){}

    login(userData: User) {
        this.sessionStore.login(userData);
    }
    logout(){
        this.sessionStore.logout();
    }
}

The dependency UserStore is defined as follows:

export function createInitialState(): User {
    return {
        id: 0, password: "", role: undefined, username: "",
    }
}
@Injectable()
@StoreConfig({ name: 'session', resettable: true })
export class UserStore extends Store<User> {
    constructor() {
        super(createInitialState());
    }

    login(user: User){
        this.update(user);
    }

    logout(){
        this.reset();
        this.update(createInitialState());
    }

    getCurrentUser(){
        return this.getValue();
    }
}

Below is the unit test:

describe('SessionService', () => {
   // @ts-ignore
   let sessionService: SessionService;
   let userStoreMock;
   beforeEach(() => {

       userStoreMock = {
           login: jest.fn(),
           logout: jest.fn()
       };

       TestBed.configureTestingModule({
           providers:[{ provide: UserStore, useValue: userStoreMock}]
       });

       sessionService = TestBed.get(SessionService);
   });

    it('should be defined', () => {
        expect(sessionService).toBeDefined();
    })
});

The error that I am encountering is:

TypeError: Cannot read property 'getComponentFromError' of null

Answer №1

If you want to simulate a service, you can create a spy object using the jasmine.createSpyObj method for the specific methods you intend to use. After that, you can mock the return values for those methods.

Here's an example:

let mockService;

mockService = jasmine.createSpyObj(['methodOne', 'methodTwo']);
mockService.methodOne.and.returnValue(of(MOCKED_DATA_1));
mockService.methodTwo.and.returnValue(of(MOCKED_DATA_2));

Then, you can assign this mockService to the providers array within configureTestingModule:

TestBed.configureTestingModule({
   ...
   providers: [
       ...
       {
           provide: MyService, useValue: mockService
       }
   ]
})

Answer №2

SessionService is not included in the providers array.

You need to update the configuration as shown below:

TestBed.configureTestingModule({
    providers:[
        SessionService,
        { provide: UserStore, useValue: userStoreMock}
    ]
});

If you still encounter the same issue, add the following code inside the beforeEach() function:

TestBed.resetTestEnvironment();
 TestBed.initTestEnvironment(BrowserDynamicTestingModule,
    platformBrowserDynamicTesting());

Test.ts

import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

declare const require: any;

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

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

The Angular project encounters a failure when attempting to run 'ng serve,' resulting in an emitted 'error' event on the worker

Resolved Issue - Update: It appears that the problem was due to an error in my CSS code: Previous: .title & .smaller { color: $dark-blue; font-family: "Roboto"; font-size: 20px; font-weight: 600; width: fit-content; margin: 0; ...

What could be the reason for the TypeScript compiler not recognizing tsconfig.json?

I recently came across a file from a tutorial that has left me confused due to the inconsistency between documentation, tutorials, and examples: /scripts/tsconfig.json: { "compilerOptions": { "emitDecoratorMetadata": true, "experiment ...

Creating a default option of "please select" on an Angular select element with a null value for validation

Within my Angular application, I am using a select element with an ngFor loop: <select formControlName="type" required> <option *ngFor="let type of typeList" [ngValue]="type.value">{{ type.caption }}</option> </select> When view ...

When using Angular's `createComponent()` method, an error may be thrown with the message "ERROR TypeError: Cannot add

I am currently working on a project where I am dynamically creating components. The component's class is being passed via an ngrx action and the process involves: loadComponent(componentType: Type<any>): void { const viewContainerRef = this.co ...

Drag events fail to activate

I am facing an issue with draggable events. Even though dragStart is functioning perfectly, drag and dragEnd events are not being triggered. Below is the HTML Element in question: <div [ngClass]="select ? 'show-re' : 'hide-re'" *ng ...

Developing a custom functionality to retrieve a server cookie for authentication in NextJS version 14

I am in the process of incorporating an email address verification feature for users registering on my NextJS website with a WordPress installation as a headless CMS. Here's what I plan to do: Set a server token with the following value {id: <use ...

Saving files to MinIO from an Angular2 web form

I am currently working on a prototype for an Angular8 application that is capable of uploading files from a form to MinIO. Below is the structure of the form: upload-form.component.html : <input class="form-control" type="file" (change)="onFileCha ...

Issue with Angular 5 and ngx-intl-tel-input integration

I've been attempting to utilize the ngx-intl-tel-input package. In my module.ts file, I have included the following: import {NgxIntlTelInputModule} from "ngx-intl-tel-input"; import {BsDropdownModule} from "ngx-bootstrap"; @NgModule({ imports: [ ...

The OR operator in TypeORM allows for more flexibility in querying multiple conditions

Is there any OR operator in TypeORM that I missed in the documentation or source code? I'm attempting to conduct a simple search using a repository. db.getRepository(MyModel).find({ name : "john", lastName: "doe" }) I am awar ...

What is the best way to sort an array based on a person's name?

I have a list of different groups and their members: [ { "label": "Group A", "fields": [ { "value": "color1", "name": "Mike" }, { &quo ...

What is the process for an Angular Component to receive a return object from a service following an HTTP

I am currently working with angular 4. Is there a way to retrieve an object from a service in this framework? export class LoginRequest { username : string; password : string; } export class LoginResponse { token : string; message : string; sta ...

Utilizing backbone-forms in Typescript: A beginner's guide

Currently in my project, I utilize backbone.js along with typescript. My goal is to incorporate backbone-forms for form creation, however I am unable to locate a typescript definition file (d.ts) for this specific backbone plugin. Despite my attempts to cr ...

Utilizing ngFor to iterate over items within an Observable array serving as unique identifiers

Just starting out with Angular and I'm really impressed with its power so far. I'm using the angularfire2 library to fetch two separate lists from firebase (*.ts): this.list1= this.db.list("list1").valueChanges(); this.list2= this.db.list("list2 ...

Spread operator in Typescript for complex nested collection types

I have implemented a Firestore database and defined a schema to organize my data: type FirestoreCollection<T> = { documentType: T; subcollections?: { [key: string]: FirestoreCollection<object>; }; }; type FirestoreSchema< T exte ...

What is the best way to create and manage multiple collapsible Material-UI nested lists populated from an array with individual state in React

In my SideMenu, I want each list item to be able to expand and collapse independently to show nested items. However, I am facing the issue of all list items expanding and collapsing at the same time. Here is what I've attempted: const authNavigation ...

Every Angular project encounters a common issue with their component.ts file

After watching several Angular 7 project tutorials on YouTube, I found myself struggling with a basic task - passing a name from the component.ts file to the component.html file. The current output of my code simply displays "Hello" without the actual nam ...

The JestImportMeta interface is mistakenly extending the ImportMeta interface, causing an error

While transitioning from jest version 27 to v29, I encountered this issue: node_modules/@jest/environment/build/index.d.ts:329:26 - error TS2430: Interface 'JestImportMeta' improperly extends interface 'ImportMeta'. The types returned ...

Tips for securely passing props based on conditions to a functional component in React

I came across this situation: const enum Tag { Friday: 'Friday', Planning: 'Planning' } type Props = { tag: Tag, // tour: (location: string) => void, // time: (date: Date) => void, } const Child: React.FC<Props> = ...

Managing CORS in Angular2 for REST WebApi calls

Currently, I am utilizing an Angular 2 front end along with a WebApi backend where the WebApi is CORS enabled. var cors = new EnableCorsAttribute("*", "*", "*"); GlobalConfiguration.Configuration.EnableCors(cors); This setup works well with different sit ...

What is the best way to send data to a child component in Angular, including components that can be

There are two components in my project: the parent component and the child component, each with their own unique markup. It is crucial for this example that the child component fetches its own data to render and not be provided by the parent. Currently, th ...