Observable<void> fails to trigger the subscriber

I am currently facing a challenge with implementing a unit test for an Observable in order to signal the completion of a process. While there is no asynchronous code in the logout function yet, I plan to include it once the full logic is implemented. The main objective here is to have the observable trigger the subscriber upon completion of the logout process without returning any data.

However, my unit tests have highlighted that the subscriber is not being invoked as expected. Typically, I work with async/await due to issues with Observables like this one, but I am trying to improve my skills in front-end development which often favors Observables.

This issue has occurred in a new Angular 9 application that I am setting up. The unit tests are conducted using Jest and run through Wallaby.

Here's what I have tried so far:

To test my unit test, I intentionally introduced a flaw into the function.

https://i.stack.imgur.com/0ZUV6.png

On line 63 of my tests, Wallaby displays a grey box indicating that the test did not execute that particular line. Consequently, the test passed without verifying the assertion made.

If I modify the observable to return a value, I get the line to execute... partially.

https://i.stack.imgur.com/QJI4M.png

Despite this change, I do not receive the expected failure message from my mock. It should indicate "expected clearSession() to be called 1 times, was 0".

When running Jest to gain further insights, I encountered the following error:

FAIL  src/app/auth/auth.service.spec.ts
● AuthService › logout › should destroy the session

1 timer(s) still in the queue.

  at node_modules/zone.js/dist/fake-async-test.js:621:31
  at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:386:30)
  at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:117:43)
  at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:385:36)
  at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/dist/zone.js:143:47)

In an odd turn of events, fixing the function resolves all issues. However, this only works when the Observable returns a value, even though its purpose is to simply notify the process completion. Despite this, I have not been able to trigger a failing assertion directly related to the logout process; instead, the failure seems unrelated (e.g., the timer in queue).

https://i.stack.imgur.com/jM2QM.png

The verify function utilized is from ts-mockito, which functions similarly to

expect(someSpy).toHaveBeenCalledTimes()
.

Are there any nuances regarding Observables that I might be overlooking?

Answer №1

I reached out for help on Reddit yesterday and received a solution to my problem, so I'm sharing it here in case anyone else is facing the same issue.

Make the switch from of() to of(undefined)

https://i.stack.imgur.com/2IqOg.png

Answer №2

Replacing() with of(undefined) is effective

it('should trigger myFunc', fakeAsync(() => {
    myService = TestBed.inject(MyService);
    const mockResponse: Observable<void> = of(undefined);
    spyOn(myService , 'myFunc').and.callFake(() => mockResponse);
    tick();
    fixture.detectChanges();
    component.myMethod();
    expect(myService.myFunc).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

Personalized Element Commands and features

UniquePage.html <div ng-controller="UniquePageCtrl"> <unique-custom-directive arg1="{{currentObj.name}}"></my-custom-directive> <div> in UniquePageCtrl.js (Controller) app.controller("UniquePageCtrl", ["$scope", function ($sc ...

"Proper Installation of Angular Project Dependencies: A Step-by-Step

Whenever I clone an Angular project with older versions that are missing the node_modules folder, and then run npm install to install all necessary dependencies, I end up receiving numerous warnings and errors related to version mismatches. Here are some ...

Encountering the error message "React child cannot be an object" while trying to map over an imported object referencing components

I have an array in a separate file that I import and iterate over in another component. One of the properties within this array, labeled component, actually refers to a different individual component. I am attempting to render this component, but I keep e ...

I have been attempting to implement validation in JQuery, but it doesn't seem to be functioning correctly

Can someone assist me with adding validation in jQuery? I'm stuck and need help solving this problem. $(function(){ $("#btn").click(function(){ var b=prompt("Enter your link"); $("a").attr("href",b); if($("b").v ...

Struggling with a component that won't load in JSX?

Having some difficulty with React not rendering data associated with a component's props: import React from 'react'; import {ItemListing} from './ItemListing.js'; export var SearchResults = React.createClass({ render: functi ...

From HTML to Mat Table: Transforming tables for Angular

I am currently facing a challenge with my HTML table, as it is being populated row by row from local storage using a for loop. I am seeking assistance in converting this into an Angular Material table. Despite trying various suggestions and codes recommend ...

Troubleshooting a JavaScript error while attempting to execute a function from a

I have been working on a new JavaScript library named TechX. Check out the code snippet below: (function(){ function tex(s){ return new tex.init(s); }; //initiate the init selector function tex.init = function(s ...

Angular Material calendar tool customization for designated input

Is it possible to individually control the format of input for a datepicker without affecting the format for the entire module? <input matInput [matDatepicker]="dp" [formControl]="date" [format]="'DD/MM/YYYY'"> <-- Can this be done? < ...

The process of invoking the AsyncThunk method within the Reducer method within the same Slice

Within my slice using reduxjs/toolkit, the state contains a ServiceRequest object as well as a ServiceRequest array. My objective is to dispatch a call to a reducer upon loading a component. This reducer will check if the ServiceRequest already exists in ...

No invocation of useEffect

I am facing an issue with my React app at the moment. My high-level useEffect is not being triggered, although it works in another project with similar code. Typically, the useEffect should be called every time I make an HTTP request from the app, but noth ...

The value of an Angular array seems to be disappearing after being copied to another array and then cleared

I have encountered an issue while working with arrays. I am initializing two arrays - one with some values and another as empty. However, when I assign the items from the first array to the second array and then clear the first array, it unexpectedly clear ...

What is the purpose of importing the HttpClientModule in app.module.ts when it has already been imported in a different module specifically for its use?

Currently, I am working with 2 modules named AppModule and BookModule. In BookModule, a component is injected with a service that utilizes HttpClient, so I had to import HttpClientModule in it. However, the application still requires importing HttpClientMo ...

What is the best way to keep track of dynamically inserted input fields?

I've created a form with two text boxes: one for entering people's "name" and another for their "surname." By clicking on the page, you can add additional pairs of text boxes for both "name" and "surname," allowing users to input as many pairs as ...

Using blending modes with gradient colors in an SVG design

I'm struggling to get my logo to change colors upon scrolling into a button with similar gradient colors, but I just can't seem to make it work. Can anyone lend me a hand? Thank you! Take a look at my Logo. I've attempted to add some styles ...

When the condition within the click function is met, concatenate the variable

I'm currently working on a function that involves adding "http://" to the variable 'bar' if it's not already included. This modified 'bar' value will then be sent via ajax to be inserted into the database and also displayed ba ...

What is the best way to incorporate external HTML content while ensuring HTML5 compatibility? Exploring the different approaches of using PHP, HTML

While this may seem like a simple task to the experts out there, I have been struggling for over an hour without success... My objective is to use a single footer file and menu file for all my webpages while considering blocking, speed, and other factors. ...

Combining Jquery with Append to Dynamically Update PHP Variables

Code Snippet (index.html) <script> $(document).ready(function() { var interval = setInterval(function() { $.get("load_txt.php", { 'var1': 4, 'var2' : 52}, function(data){ $('#msg' ...

What is the best way to invoke a TypeScript function within a jQuery function?

Is it possible to invoke a TypeScript function within a jQuery function? If so, what is the correct approach? Here is an example of my component.ts file: getCalendar(){ calendarOptions:Object = { height: 'parent', fixedWeekCount : ...

Tips for incorporating a multiple tag search feature within my image collection using JavaScript?

I am facing a challenge with my image gallery search feature. Currently, users can search for images by typing in the title or tag of an image. However, I need to enhance this functionality to allow for multiple tags to be searched at once. For example, if ...

Submitting the form without utilizing Ajax, but instead sending data directly to a PHP script

I've encountered an issue while posting a form to a PHP file using AJAX. Despite my efforts, the form is bypassing AJAX and posting directly to the PHP file. Here is my form: <form id="editform" name="editform" action="ajaxeditform.php" method= ...