how to test $window.open using jasmine

All we need is an easy explanation of the problem, so here it is.

This is my function

 $scope.buildForm = function (majorObjectId, name) {
      $window.open("/FormBuilder/Index#/" + $scope.currentAppId + "/form/" + majorObjectId + "/" + name);
  };

This is my jasmine test spec

            it('should open new window for buildForm and with expected id', function () {
            scope.majorObjectId = mockObjectId;
            scope.currentAppId = mockApplicationId;
            var name = "DepartmentMajor";
            scope.buildForm(mockObjectId, name);
            scope.$digest();
            expect(window.open).toHaveBeenCalled();
            spyOn(window, 'open');
            spyOn(window, 'open').and.returnValue("/FormBuilder/Index#/" + scope.currentAppId + "/form/" + scope.majorObjectId + "/" + name);
        });

but when i try to run this it is opening a new tab and i don’t want this to happen, i just want to check whether the given returnValues are present are not!!

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

First of all your expectation (window.open).toHaveBeenCalled() is in wrong place.
You cannot expect before spying the event.
Now coming to your question
there are different methods in jasmine to spy on dependencies,like

  • .and.callThrough – By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation.
  • .and.callFake – By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function.
  • .and.returnValue – By chaining the spy with and.returnValue, all calls to the function will return a specific value.

Please check Jamine doc for complete list

Sample test case for below as per your requirement

$scope.buildForm = function() {
        $window.open( "http://www.google.com" );
    };

Will be

it( 'should test window open event', inject( function( $window ) {
        spyOn( $window, 'open' ).and.callFake( function() {
            return true;
        } );
        scope.buildForm();
        expect( $window.open ).toHaveBeenCalled();
        expect( $window.open ).toHaveBeenCalledWith( "http://www.google.com" );
    } ) );

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply