Combining Jasmine 2.0's async done() with angular-mocks inject() in a single test case

Typically, my test cases are structured like this:

it("should send get request", inject(function(someServices) {
     //some test
}));

However, for Jasmine 2.0 async tests, the format changes to:

it("should send get request", function(done) {
     someAsync.then(function(){
         done();
     });
});

Is it possible to incorporate both 'done' and 'inject' in a single test?

Answer №1

I encountered a similar issue after updating to Jasmine 2.0, but I managed to resolve it with the following solution.

it("should perform a get request", function(done) {
    inject(function(someServices) {
        //performing an asynchronous test here
        done();
    })(); // remember to invoke the function returned by 'inject'
});

Answer №2

A crucial point to note is the inclusion of brackets after the inject function call. For example:

inject(function(someServices) {
   //some asynchronous test
   done();
})();  <-- these brackets are important here.

If you examine the type of inject:

export declare function inject(tokens: any[], fn: Function): () => any;

You can see that it returns a function, which explains why there was no output - because you forgot to invoke the function!!

When you think about it, it makes sense that it returns a function since it expects a function!

Therefore, adding extra parentheses should resolve all issues!

Example in Action:

  it('should allow you to observe for changes', function(done) {
    inject([GlobalStateService], (globalStateService: GlobalStateService) => {
      globalStateService.observe("user", storageType.InMemoryStorage, (user: string) => {
        expect(user).toBe("bla");
        done();
      });

      globalStateService.write({ user: "bla"}, storageType.InMemoryStorage);
    })();
  });

Answer №3

In response to @Scott Boring's answer and @WhiteAngel's comment highlighting that the code within inject was not executed.

I found a solution that worked for me:

it("should execute get request", function(done) {
    inject(function(someServices) {
       //performing asynchronous test
       done();
    })();
});

Answer №4

Here is an example of how the test could be written:

describe("Testing a service'", function () {    
    var myService;
    var testData;

    beforeEach(function (done) {   
        module('myApp');

        inject(function (someService) {
            myService = someService;
        });

        myService
            .getTestData()
            .then(function(result) {
                testData = result;
                done();
            });
    }); 

    it('should have test data available', function () {  
        expect(testData).toBeDefined();
    }); 
}

Answer №5

I encountered an issue with @scott-boring's method in Angular 5.2.0 which led me to try a different approach. I found success by utilizing TestBed.get() instead of inject() when accessing services, as detailed in the official documentation:

describe('TooltipComponent', () => {
  let component: TooltipComponent;
  let fixture: ComponentFixture<TooltipComponent>;
  let myService: MyService;

  beforeEach(async(() => {
    const myServiceSpy = jasmine.createSpyObj('MyService', ['calc']);

    TestBed.configureTestingModule({
      declarations: [ MyComponent ],
      providers: [
        {provide: MyService, useValue: myServiceSpy}
      ]
    })
    .compileComponents();

    myService = TestBed.get(MyService);
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should render correctly', (done) => {
    component.render();

    setTimeout(() => {
      expect(myService.calc).toHaveBeenCalled();
      done();
    }, 1000);
  });

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

Issue with THREE.SpriteCanvasMaterial functionality

This unique piece of code (inspired by this and this example): generateCircle = (ctx) -> position = 0.5 radius = 0.5 ctx.scale(0.05, -0.05) ctx.beginPath() ctx.arc(position, position, radius, 0, 2*Math.PI, fa ...

Utilizing the filter function iteratively within an Angular factory component

I am facing an issue where I have a factory with 2 controllers. The first controller returns an entire array, while the second controller is supposed to return only one item based on a specific filtering expression. I need to extract the last two parameter ...

Is there a way to combine multiple images into one PDF document using Html2Canvas and JsPDF?

Trying to understand the HTML2Canvas API has been quite challenging due to the limited documentation available. My goal is to place multiple div elements, each representing a different page, into a single PDF file. It might sound simple at first, but in re ...

Unable to simulate the Enter key press event for a text area using Angular 7

I've implemented a feature that allows users to type something and then press the submit button, at which point the cursor should move to the next line. If the user types some words and presses the Enter key, the cursor should also shift to the next l ...

The attribute on the label fails to trigger any action on the linked input upon clicking, due to the binding of the id and for

My component is designed to display a checkbox and label, with inputs for id, name, label, and value. Here's the code: <div class="checkbox col-xs-12" *ngIf="id && name && label && value"> <input type="checkbox" ...

Determine which scroll bar is currently in use

I'm running into an issue with multiple scrollbars on my page - they just don't seem to be functioning correctly: <div class="dates-container" v-for="id in ids"> <overlay-scrollbars :ref="`datesHeader` ...

Is the initial carousel element failing to set height to 100% upon loading?

If you take a look here, upon loading the page you will notice a DIV at the top. It is labeled "content" with "content_container" wrapped around it and finally, "page" around that. Clicking the bottom left or right arrows reveals other DIVs with similar ta ...

Executing a function by click event using the onclick attribute from a file located in the public directory of my project (Next

I'm new to using Next.js and I have a question about how to utilize onclick to execute a function from an external file located in my public folder. Below is my index.js file: import Head from "next/head" import Script from "next/scrip ...

What is the best approach for managing Create/Edit pages in Next.js - should I fetch the product data in ServerSideProps or directly in the component?

Currently, I am working on a form that allows users to create a product. This form is equipped with react-hook-form to efficiently manage all the inputs. I am considering reusing this form for the Edit page since it shares the same fields, but the data wil ...

Blurring images with a combination of jQuery Backstretch and Blurjs

I have a background image displayed using Backstretch and want to apply Blur.js to blur elements on top of it. However, when I try to use Blur.js on the backstretched image, it doesn't work. I believe this is happening because Blur.js uses the CSS pro ...

Code for jQuery function

How do I update textareas with values after submitting a form? Below is the HTML code: <form id="productionForm" name="productionForm" method="POST"> <input type="text" id='ime_2'/> <textarea id='text_2'>& ...

Exploring the interactive doughnut graph using SVG and Vue.js

Looking to create a unique dynamic donut chart using SVG and Vue. I want it to mirror the exact SVG format found on this webpage: (To see the animated chart, select a dish and click on ingredients) This might not have been the best approach, but it was ...

Determining object types based on sibling properties in Typescript

Can you define properties of an object based on another property within the same object? How do I determine the types for values based on the value of the type property? type StepKeys = "Test1" | "Test2"; interface objectMap { &qu ...

Removing a child element in ReactJS that was dynamically created based on a count

Currently, I'm working on a project with two React components: TrackSection (the parent element) and TrackItem (the child). The TrackSection contains a button that adds a new TrackItem every time it is clicked by incrementing the numTracks variable. W ...

Update an array by breaking it into smaller chunks, while maintaining the original index positions

I am faced with a situation where I must update an existing array by utilizing its chunks to perform a specific operation. While I have a functional solution in place, I am concerned about the performance implications and I am eager to determine if my curr ...

What could be the reason for my Flask-SocketIO server failing to properly transmit messages to the client-side JavaScript?

I am currently collaborating on a home automation project using raspberry pi3 and flask. My main goal is to send real-time information that can be displayed on a web page (html + javascript). To achieve this, I have incorporated the flask-socketio extensio ...

Could you lend a hand in figuring out the root cause of why this Express server is constantly serving up error

I am encountering a 404 error while running this test. I can't seem to identify the issue on my own and could really use another set of eyes to help me out. The test involves mocking a request to the Microsoft Graph API in order to remove a member fro ...

What could be causing the Javascript Dynamic HTML5 Table to not display on the page?

I have a program that calculates the total price of products based on a specified quantity and updates an HTML table with these values. To demonstrate this, I am constantly taking input using an infinite loop. <!DOCTYPE html> <html> ...

Filtering with multiple attributes in Angular using GroupBy

I have a set of JSON data structured like this: [ { "id": 1, "address": "MG Road", "country": INDIA, "state": AP, "city": VIJ }, { "id": 2, "address": "Miyapur", "country": INDIA, ...

Attach a click event to images that are dynamically loaded through AJAX

I've been struggling with a particular block of code, and after careful investigation, I believe I have pinpointed the issue. Let me share with you the jQuery function in question... $(document).ready(function(e) { $('#formattingSection&apos ...