Testing actual HTTP requests in unit and integration tests with AngularJS

Attempting a request that was not mocked using $httpBackend.when in an Angular 1.x unit/integration test will lead to an error:

Error: Unexpected request: GET /real-request

Is there a way to perform actual HTTP requests with ngMock and the Karma+Jasmine testing setup? What is the recommended approach for achieving this?

Answer №1

The AngularJS framework has a strong stance on HTTP requests in unit testing - all requests should be mocked.

Performing real HTTP requests in unit tests is discouraged for two main reasons. Unit tests should be fast and isolated, and making a real request can slow down the test significantly by introducing asynchrony. Additionally, using real requests breaks the isolation as the test outcome relies on both the unit being tested and the backend service.

To address this issue, AngularJS introduced the ngMock module, automatically loaded in unit tests via angular-mocks.js. This module eliminates the need for developers to perform asynchronous Jasmine unit tests with Angular.

On the other hand, integration tests differ from unit tests as they may involve testing multiple units, potentially including a backend server through real HTTP requests. In such cases, Karma and Jasmine are still used, but the tests may run slower and require asynchrony.

In E2E tests, the ngMockE2E module comes into play. While included in angular-mocks.js alongside ngMock, it's not loaded by default. This module provides mocks suitable for end-to-end testing, with features like the e2e $httpBackend mock.

ngMockE2E offers an alternate implementation of $httpBackend for this purpose, with variations in its API usage. It's recommended not to use methods like flush and extend, and instead utilize $rootScope.$digest() for executing promises.

However, integrating ngMockE2E may face challenges due to adjustments made to Angular services by ngMock. To resolve this, a helper module for integration tests such as 'ngMockI9n' can be utilized.

For smoother testing practices, a recipe for whitelisting real HTTP requests can make the process easier, though explicit enumeration of real and mocked requests is considered best practice.

In summary, when conducting integration tests that involve real requests, it's advisable to leverage $httpBackend from ngMockE2E, albeit requiring additional steps to ensure compatibility with ngMock. Avoid real requests in unit tests to maintain the speed and quality of the tests.

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

Is there a quick way to use AJAX in Rails?

By using the remote:true attribute on a form and responding from the controller with :js, Rails is instructed to run a specific javascript file. For instance, when deleting a user, you would have the User controller with the Destroy action. Then, you woul ...

What distinguishes setting a $watch on a string variable from setting a $watch on an object's key in AngularJS?

When using angularJs, I am curious about the distinction between setting $watch on a string variable versus setting $watch on an Object's key. Let me explain with a detailed scenario: $scope.activeMenu = {'id' : '...', 'name ...

How can I pass a PHP variable to a JavaScript variable using PHP and JQuery/JavaScript?

I am facing a challenge with a large <select> input that is used across multiple pages. My idea is to separate this dropdown box into its own PHP file and load it externally using JQuery. Is this approach feasible? Here's an outline of what I ha ...

What's the easiest method for moving div content from side to side?

Working on a plugin for WordPress, I am faced with the task of moving content in a slider from left to right and right to left. My current attempt is as follows: var effect = 'slide'; // Set the options for the chosen effect type var opti ...

Creating an Elastic Beanstalk instance from an s3 bucket using the aws-sdk tutorial

I am currently facing some difficulties in deploying an elastic beanstalk instance using the AWS JavaScript SDK. My goal is to have the source code come from an S3 bucket. While I know this can be done through the web interface, I am struggling to figure o ...

What steps should I follow to change the appearance of this object to match this?

Attempting to modify the value of an object nested within an array, which is in another object. The nesting might be a bit complex... Here's how it currently looks { household and furniture: [{…}, {…}], school stuffs: [{…}, {…}] } M ...

Merge nested arrays while eliminating any redundant elements

Is there a way to merge these array sets while ensuring that duplicate values are removed? I am unsure if lodash provides a solution for this specific scenario where the arrays are nested. Most of the solutions I have come across assume flat arrays. Any ...

Is it possible for PHP to return jQuery code and have it execute immediately upon being echoed?

As someone who is new to jQuery and PHP, I have been tasked by my boss to create a login system for a web page that contains sensitive company information. The challenge is that this webpage consists of just one html/php file. Here is what I have done so ...

Deactivate click events in the container div

Here is the html code snippet that I am working with: <div class="parent" ng-click="ParentClick()"> . . . <div class="child" ng-click="ChildClick()"> Some Text </div> </div> When clicking on Som ...

Sending a variable to an AngularJS factory

I am currently working on a select list that looks like this: <select name="make" class="form-control" ng-model="selectCity"> <option value="Kannur">Kannur</option> <option value="Agra">Agra</option> <option va ...

When using ng-repeat with Angular ui-bootstrap and tabs, the new tab will not be selected if there are no existing tabs present

To showcase the problem I'm facing, please refer to this link: http://codepen.io/pietrofxq/pen/ZLLJdr?editors=1010 Click on "remove tabs" and then on "add tab" The challenge at hand involves using a loop with ng-repeat to display tabs. At times, the ...

"Encountering an issue with Material UI where the Theme Style typography is not

Trying to update typography in the theme using Material UI but facing issues with object changes not working. The palette, however, is functioning correctly. Attempts were made to modify H3 styles and default font size but without success. On the contrar ...

Is there a simpler method for making multiple posts using an AJAX JS loop?

My form is quite extensive and uses AJAX to save. The JavaScript functions are stored in an external file and structured like this: function milestone09() { $.post('./post.3.AIGs2GRA.php?data=' + (secData), $('#milestone09').serialize( ...

Chrome is having trouble loading basic JavaScript

Here's the JavaScript code I have placed inside the head tag of my HTML: <script type="text/javascript"> function over1() { var img1 = document.getElementById("1").src; document.getElementById("big").src = img1; } function out() { ...

What could be causing the images to not display on my HTML page?

My program is designed to display an image based on the result of the random function. Here is my HTML: <div> <h2>Player 0:</h2> <div id="MainPlayer0"></div> </div> Next, in my TypeScript fi ...

The directive fails to refresh when there are modifications made to the service model

My application's model is stored in a service: angular.module('adminClient').factory('myApi', function () { var model = {}; model.myObject = { label: 'New York City' }; return { model: fu ...

Transforming a PHP cURL call to node.js

Currently exploring the possibility of utilizing the Smmry API, however, it seems that they only provide PHP API connection examples. Is there anyone who could assist me in adapting it into a JS request? My requirement is simple - I just need it to analyz ...

React Material UI issue: You cannot render objects as a React child. If you intended to display a group of children, make sure to use an array instead

I am encountering an issue with the code provided below and despite trying various fixes, I am unable to resolve it. componentDidMount() { axios.get('http://localhost:8080/home') .then((response) => { this.setState({ ...

Creating a variable to store the data retrieved from a package

Imagine you have a functioning code snippet like this: const myPackage = require('myPackage'); myPackage.internal_func(parameter).then(console.log); This outputs a JSON object, for example: { x: 'valX', y: 'valY' } ...

Determining the minimum and maximum values of a grid using props in a React component

I have created a code for a customizable grid screen that is functioning perfectly. However, I am facing an issue where I want the minimum and maximum size of the grid to be 16 x 100. Currently, when a button is clicked, a prompt window appears asking for ...