Unit testing an Angular service using Jasmine with a JSON object schema in Angular 2/4

Looking for assistance with unit testing a service I have. The service includes a current json array object that is functioning properly when the observable is subscribed to.

However, I seem to be encountering issues with my unit test setup. Can anyone provide guidance on what I might be doing wrong?

Service Code

getTrackerData(): (Observable<any>) {
    return Observable.of(tracker)
        .do(data => console.log('trackerdata', data))
        .catch(this.handleError)
}

private handleError(error: Response) {
    console.error(error);
    return Observable.throw(error.json().error || 'Server error');
}

}

DATA

const tracker =
[{
    "tracker": "2278474849", "task": 1, "agent": 1, "session": "2278474849-1-1"
 }
]

Unit Test

/// <reference path="../../../../node_modules/@types/jasmine/index.d.ts" />
import { TestBed, fakeAsync, inject, tick, async, ComponentFixture, ComponentFixtureAutoDetect } from '@angular/core/testing';
import { MockBackend } from '@angular/http/testing'
import { Http, BaseRequestOptions, Response, ResponseOptions } from '@angular/http'
import { BrowserModule, By } from "@angular/platform-browser";
import { ReactiveFormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Rx'
import { TrackerService } from './tracker.service'


describe('tracker service', () => {

    let mockResponse, matchingItem, connection

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            providers: [
                TrackerService,
                MockBackend,
                BaseRequestOptions,
                {
                    provide: Http,
                    useFactory: (backend, defaultOptions) => new Http(backend, defaultOptions),
                    deps: [MockBackend, BaseRequestOptions]
                },
            ]
        });
        const items =
            [{
                "tracker": "2278474849", "task": 1, "agent": 1, "session": "2278474849-1-1"
            }
            ];
        mockResponse = new Response(new ResponseOptions({ body: items, status: 200 }));
    }));


    describe('getTrackerData', () => {
        //subscribe to connection and storing it later
        it('should return all items', inject([TrackerService, MockBackend], (service: TrackerService, backend: MockBackend) => {
            backend.connections.subscribe(connection => {
                connection.mockRespond(mockResponse);
            });
            service.getTrackerData() //{ "tracker": "2278474849", "task": 1, "agent": 1, "session": "2278474849-1-1"  }
                .subscribe((items: any => {
                   expect(this).toBe(2);
            }));

    })

});

Experiencing difficulties in the describe section, as I am fairly new to writing javascript/angular unit tests and have been mixing different examples from my project and online resources which has led to confusion.

It seems like the solution should be straightforward, but the abundance of dependencies I imported has made the process more complex than necessary. Any suggestions on what steps I should take?

Answer №1

When testing services, I have been utilizing the service instance obtained from the getTestBed function. Consider updating the inner describe block as follows:

describe('getTrackerData', () => {
    it('should return all items', (done) => {
        let service: TrackerService;
        let bed = getTestBed();

          backend.connections.subscribe(connection => {
              connection.mockRespond(mockResponse);
          });

          service = bed.get(TrackerService);

          service.getTrackerData()
              .subscribe((items: any) => {
                 expect(this).toBe(2);
                 done();
          });
})

Ensure to import getTestBed from '@angular/core/testing'. You may also want to review if the following imports are necessary:

import { BrowserModule, By } from "@angular/platform-browser";
import { ReactiveFormsModule } from '@angular/forms';
import { Observable } from 'rxjs/Rx'

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

Why would someone opt to utilize process.env.PORT in their code?

Setting the environment variable PORT to a specific value, such as set PORT=5000, provides explicit instructions on which port the program should use. How does this method differ from simply instructing it to use port 3000? ...

Utilizing HTML/CSS with React/Bootstrap: A Comprehensive Guide

Looking for help with integrating HTML/CSS code into React/Bootstrap? I need assistance with coding in React using Bootstrap. How do I effectively use components and props? Even after installing bootstrap, I am encountering errors. Is it possible to dire ...

Issue with date comparison operator logic

Here's a simple JavaScript function I have: function checkTime() { var current = new Date(); var target = new Date('April 10, 2017 12:11:00'); if (current < target) { $('#modalnew').modal('show'); } els ...

Storing data from PHP in Local Storage using JavaScript variable

When a specific build name is clicked, the inner HTML content is captured and assigned to a JavaScript variable called loadDump. This variable is then sent over to PHP via an AJAX request. $.ajax({ url:"http://custom-assembly.tcad.co.uk/wp-content/t ...

I am attempting to rebuild Vuex's Getting Started example by utilizing multiple components, yet I am struggling to understand how to call root methods from within these components

The project I'm working on can be found here. It is a simple one, but for the purpose of learning, I divided it into index and four js files (parent, child, root, and store). My challenge lies in figuring out how to call the increment and decrement ro ...

What is the best way to store selected items from a multi-select box in AngularJS that is generated using ng-repeat?

I have a scenario where I need to handle a group of select boxes instead of just one. Each select box holds a different option, and when the user changes their selection, I want to save that value in a variable or an array. I've managed to do this for ...

Is my front-end JavaScript fetch request mistakenly being sent as a GET instead of a POST?

On clicking the submit button, a fetch request is triggered. Strangely, in the developer tools, it shows up as a GET request. I tested the request using Insomnia and it returned the handlebars site to me without any of my console logs appearing on either ...

The server has denied access to the resource due to a HTTP 403 Forbidden error in the AJAX request

I have exhausted all resources online in an attempt to resolve an error I am encountering with my AJAX request. Even after trying XMLHttpRequest() request, the problem remains unsolved. Below is the code for my Ajax Request: $.ajax({ type: "POST", url: " ...

Error in Compiling HTML Elements Collection<<Element>

Currently, I am developing an eCommerce application that features a popup window for users when they click on "Add to Cart." This popup allows users to select product variations and quantities before adding the item to their cart. The popup consists of a s ...

Trouble encountered with card flip style login form in Vue.js, as the card is not maintaining its position properly during transition animations

Need help styling a login/signup component in Vue.js where flipping between the two cards isn't working smoothly. The transition is causing one card to move down and right while the other comes in from the bottom right. It's hard to explain the i ...

Challenges encountered when attempting to access files from the filesystem on vercel

Currently, I am working on a website that includes a "blog" section with markdown files. The setup reads the files seamlessly from the file system without any errors... except when deployed on Vercel. In that case, it throws a "No such file or directory" e ...

Determine whether a component is linked to an event listener

If a <Form> component is called with a @cancel event listener attached to it, the cancel button that triggers this event should be visible. If no @cancel event is present, the cancel button should not be displayed. Is there a method to verify if a c ...

A guide on utilizing the index column for multiple tables using just one statement in the datatable js library

I've incorporated the datatable js for managing two tables on a single page. HTML <!-- Table#1 --> <table class="dataTable"> <thead> <tr> <td>#</td> <td>col1</td> </tr> &l ...

Modifying background with JavaScript and AJAX技术

I currently have a table structured like the following; <table style="width: 100%; border: solid 1px #666600; min-width: 800px" cellpadding="0" cellspacing="0"> <tr> <td id="aaa">&nbsp;</td> ... Using jQuery's ajax functi ...

Quasar Vue - Qselect component not populating with async data, showing [object Object] as default value

Within my created() method, I am making a call to Firestore to populate an array called ebscoCachedSearchesController in the data section. This array consists of objects that are correctly configured to be displayed in the qselect component. However, when ...

The process of transferring information from a JSON API to TypeScript models

When working with my JSON API in my services, I need to pass the data to my models. What is the most efficient way to accomplish this task? Currently, I am following this process: import { Attachment } from '.'; export class Contact { id: nu ...

Concealing HTML content with a modal overlay

There are security concerns with my authentication overlay modal, especially for users familiar with CSS and HTML. Is there a way to hide the HTML behind the modal so it doesn't appear in the page source? The code below is just an example of a modal ...

Utilizing Material UI and TypeScript to effectively pass custom properties to styled components

Currently, I am utilizing TypeScript(v4.2.3) along with Material UI(v4.11.3), and my objective is to pass custom props to the styled component. import React from 'react'; import { IconButton, styled, } from '@material-ui/core'; con ...

The Chrome extension for the New Tab Page is taking the spotlight away from the address bar

It appears that with the latest version of Chrome, extensions that previously had the ability to override Chrome's New Tab Page and take focus away from the Omnibox no longer have this capability. Is there a different method now to give focus to an i ...

How can I activate a custom event on a repeated div element in Angular 2?

I am working on a project where I need to create multiple divs using an ngFor loop. When a user clicks on one of the divs, I want to add a unique class only to that specific div. Currently, I am using a boolean flag on [ngClass] as a test case, but I am u ...