Angular JS - Checking a function with page redirection using karma / jasmine

I have a function in my Angular controller that looks like this:

$scope.myFunction = function(){ $scope.myVariable = "something"; $scope.myOtherVariable = "something else"; window.location.href = "/path/to/page"; } 

A simple Jasmine test covers the above function and is as follows:

 describe('my test', function(){ it('should pass', function(){ scope.myFunction(); expect(scope.myVariable).toBe('something'); expect(scope.myOtherVariable).toBe('something else'); }); }); 

The above test passes, but then Karma gives the following error in the console:

Some of your tests completely reloaded the page!

Redirecting a page causes Karma to raise this warning. What is the best way to get around this?

I thought about providing anonymous functions in the Jasmine test and Angular names, and then using arguements.callee.caller.name inside the original function to determine if the function is being called on its own or Jasmine. Unfortunately, arguments.callee.caller.name always returns undefined, which I suspect is caused by how Angular and Jasmine are related to each other.

+7
angularjs karma-runner jasmine karma-jasmine
source share
2 answers

For a long time, when this question was asked, but the following approach should be cleaner:

By changing the original function to use the Angular $ window service instead of the browser window object, you can write a test that does not require changing the production code or taking into account any run-time parameters. This, of course, requires that $ window depend on the controller where the function is found.

Using angular -mocks / ngMock , something like:

 var fakeWindow = { location: { href: '' } } // instantiate controller with mock window beforeEach(inject(function($controller) { $controller('YourCtrlName', { $window: fakeWindow }); })); 

should pass the test, assuming the controller does not need $ window for anything else.

+22
source share

You can simply create a function that performs navigation, for example

 $scope.Navigate = function() { window.location.href = "/path/to/page"; }; 

or even better in some service

 app.factory('navigator', function() { return { Navigate: function(path) { window.location.href = path; } }; }); 

Then in your test, you can use the spy in Navigate to be sure that the navigation has been called, but does not actually name the navigation.

+4
source share

All Articles