Mastering unit testing with Behaviour Subjects in Angular

I am looking to test the get and set methods of my user.store.ts file. The get() method is used to retrieve users, while addUsers() is utilized to add new Users to the BehaviorSubject. How can I accomplish this?

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { User } from 'ngx-login-client';

@Injectable({
  providedIn: 'root'
})

export class UserStore {

  private _users: BehaviorSubject<User[]> = new BehaviorSubject([]);

  get users() {
    return this._users.asObservable();
  }

  addUsers(users: User[]) {
    this._users.next(users);
  }
}

I expect that values will be added when addUsers() is called, and I can retrieve users by calling get users(). I am relatively new to Angular Testing.

An error message similar to the following has been appearing:

Expected Observable({ _isScalar: false, source: BehaviorSubject({
  _isScalar: false, observers: [  ], closed: false, isStopped: false, hasError: false, thrownError: null, _value: [ Object({ attributes:
  Object({ fullName: 'name', imageURL: '', username: 'myUser' }), id:
  'userId', type: 'userType' }) ] }) }) to equal [ Object({ attributes:
  Object({ fullName: 'name', imageURL: '', username: 'myUser' }), id:
  'userId', type: 'userType' }) ].

The structure of my User[] object is as follows:

{
    'attributes': {
        'fullName': 'name',
        'imageURL': '',
        'username': 'myUser'. 
    },
    'id': 'userId',
    'type': 'userType'
}

Update: My user.store.spec.ts file.

import { TestBed, async } from '@angular/core/testing';

import { UserStore } from './user.store';
import { BehaviorSubject } from 'rxjs';
import { User } from 'ngx-login-client';

describe('UsersStore', () => {
  beforeEach(() => TestBed.configureTestingModule({}));

  it('should be created', () => {
     const store: UserStore = TestBed.get(UserStore);
     expect(store).toBeTruthy();
  });
  it('should add Users', async(() => {
    let store: UserStore;
    store = TestBed.get(UserStore);
    let user: User[];
    const testUser: User[] = [{
      'attributes': {
      'fullName': 'name',
      'imageURL': '',
      'username': 'myUser'
    },
    'id': 'userId', 
    'type': 'userType'
   }];
   store.addUsers(testUser);
   store.users.subscribe(users => {
     expect(users).toBe(testUser);
     });
  }));
});`

Answer №1

As mentioned in the error message, the provided data is Observable while your test scenario expects an Object.

To rectify this issue, you should structure your test case as follows:

it('should retrieve users', async(() => {
  component.users.subscribe(users => {
    fixture.detectChanges()
    expect(users).toBe(testUsers)
  })
}))

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 proper way to utilize useRef in TypeScript to assign a function to ref?

I am just diving into Typescript and I am looking to assign a function to a ref within a custom hook. My goal is for the function to remain constant throughout renders. Check out the code on CodeSandbox: https://codesandbox.io/s/918l0wro4r function runFu ...

Creating a TypeScript declaration file for a singular module

Consider the following directory structure: src/ ├── foo.ts ├── bar.ts ├── baz.ts ├── index.ts If foo.ts, bar.ts, and baz.ts each export a default class or object, for example in foo.ts: export default class Foo { x = 2; } I ...

What could be causing the angular Data table to not display properly?

I am currently exploring Angular Datatables and have a question about re-rendering the datatable after it has been hidden. Can anyone provide guidance on how to achieve this? In my project, I have two components - Parent and Child - that can be hidden or ...

"Augury Angular 2 is like a tree that generates insights like no

As I work on documenting my project, I am looking to create documentation that will make it easier for beginners to understand the project's structure in the future. I am using Angular2 and documenting with Typedocs. My question is: Are there any solu ...

What is the best way to identify the main dark color in Angular Material, and what other color variables are available for use with Angular Material?

Hey there, I'm trying to figure out how to utilize the primary dark color from angular material. I attempted using color="p-dark" but it doesn't seem to be working. Any ideas on how to access the dark color defined by the material color tool? I w ...

Discovering the parameter unions in Typescript has revolutionized the way

My current interface features overloaded functions in a specific format: export interface IEvents { method(): boolean; on(name: 'eventName1', listener: (obj: SomeType) => void): void; on(name: 'eventName2', listener: (obj: Som ...

Encountering an error with 'ng serve' on a recently established Angular project

After installing nodejs and Angular on my Windows 11 machine, I created a project using the ng new command. However, when I tried to run it with ng serve, I encountered the following error: c:\working\projects\xxxxxxx\xxxxxx-site>ng ...

What is the process for uploading an array of files with AngularFire2 and Firebase Storage?

I encountered a dilemma trying to find answers to my question. Most resources, like the AngularFire2 documentation and an informative tutorial from angularfirebase.com, only demonstrate uploading one file at a time. As I aim to construct a photo gallery CM ...

TypeScript's type inference feature functions well in scenario one but encounters an error in a different situation

I recently tried out TypeScript's type inference feature, where we don't specify variable types like number, string, or boolean and let TypeScript figure it out during initialization or assignment. However, I encountered some confusion in its be ...

Is there a way in Angular Material to consistently display both the step values and a personalized description for each step?

Is there a way to display both numerical step values and corresponding custom text in Angular Material? I prefer having the number at the top and the descriptive text at the bottom. Check out this image for reference: https://i.stack.imgur.com/LGMIO.png ...

Enhance Typescript with Extension Traits

Picture this scenario: You have a class A with a method that can create an instance of class B. You're unable to make any changes to the code of either A or B, as they are part of an external library. In this situation, if you want to enhance the fun ...

Having difficulty parsing the text into individual components found within the Feature modules

In my Shared module, I have a component that requires localization using NGX-TRANSLATE. However, it seems like the component in the shared module is not able to access the JSON file loaded in app.module.ts, resulting in the error: "Cannot read property &ap ...

Having trouble running tests with Sequelize in Jest?

Challenge Encountering an error while attempting to run Jest testing on my Express application. The error message reads as follows: FAIL models/tests/user.model.test.js ● Test suite failed to run TypeError: Sequelize is not a constructor 2 | cons ...

A guide on harnessing the power of Jest when integrating it with vuex-module-decor

In my Typescript-written Vue component, I am facing an issue while trying to write a unit test using vue-test-utils and jest. The problem arises when injecting the vuex store that was created with vuex-module-decorators. Below is a snippet from my Vue com ...

What is the method for adjusting the time format?

Using the TIME data type, my data is currently displayed in the format hh:mm:ss (03:14:00). How can I change it to display in the format hh:mm (03:14)? The usual DATE type method does not seem to work: {{test.time | date: 'HH:mm'}} However, thi ...

Make sure accordion items stay open even when another one is clicked

I have implemented an accordion component that currently opens and closes on click. However, I am facing an issue where clicking on one item closes another item that was previously open, which is not the behavior I desire. I'm unsure of the best appro ...

Mastering Light and Camera Selection in Three.js

Question, In the editor found at this link, you can click on a light or camera to select it. I am familiar with using raycaster.intersectObjects(objects) to select meshes, but how can I achieve the same result for lights and cameras which do not have mesh ...

Strategies for navigating dynamic references in Angular 2 components

I am working with elements inside an ngFor loop. Each element is given a reference like #f{{floor}}b. The variable floor is used for this reference. My goal is to pass these elements to a function. Here is the code snippet: <button #f{{floor}}b (click) ...

Typescript's forEach method allows for iterating through each element in

I am currently handling graphql data that is structured like this: "userRelations": [ { "relatedUser": { "id": 4, "firstName": "Jack", "lastName": "Miller" }, "type": "FRIEND" }, { "relatedUser": ...

What could be the reason for the absence of Mock Service Worker in a React project that has Typescript enabled?

After attempting to integrate Mock Service Worker into my React project with Typescript support, I encountered errors when running the npm install msw --save-dev command. The terminal displayed the following messages: PS F:\Programming\React Prac ...