jasmine mock window object

58,261

Solution 1

The problem is that you just overwrite a property of the window object. And if you can do that, the browser can do that as well. So mocking a function or property of a global object that everyone can access isn't a good idea in general, because you can never be sure that your changes will be there when you try to access them.

Which brings me to dependency injection. Its a common pattern to make your code unit testable, with a focus on unit. Whats does it mean. When ever you create a new object or access a global object, you're not only testing your unit functionality, but also the functionality of your newly created or global object. To prepend that, you not create the new objects in your unit, but pass them into. Normally you would to this in the constructor, but as in JavaScript function are objects with the function body as constructor, you can also pass the dependencies simply into your function.

So in your case, the function depends on the global window object. So instead of trying to access the global window object, pass it as a parameter into your function. Doing it this way you can pass in the window object in your production code and a simple JavaScript object with an arguments atribute into your test:

function youWannaTest(w){
    console.log(w.arguments[0]);
}

In your extension call the function like this:

youWannaTest(window);

In your test call the function like this:

youWannaTest({arguments: ['someValue']});

Solution 2

I also think dependency injection is the cleanest solution.

Your JS:

function submit(_window) {
    _window = _window || window
    ...
    var url = _window.arguments[0];
    ...
}

Your unit tests:

it('works like a dream', function () {
    var _window = { arguments: ['url'] }
    expect(submit(_window)).toBeTotallyAwesome()
})

Solution 3

Yes, You can mock window object.

The first thing you will have to do is make one change in your JS code : Replace window with $window.

Then, You can mock window using below code:

var window = {
  arguments : ['url']
};

now in your spec file : in beforeEach block

$controller('controllerName', {$window : window});
Share:
58,261

Related videos on Youtube

toy
Author by

toy

This space is intentionally left blank.

Updated on July 09, 2022

Comments

  • toy
    toy almost 2 years

    How do I mock window object? I'm doing firefox extension and I want to use jasmine for javascript testing.

    In my javascript I have

    
    function submit() {
    ...
    var url = window.arguments[0];
    ...
    }
    
    

    Obviously, I have to mock window.arguments[0] in jasmine because that object doesn't exists if not passing any parameter from window.openDialog

    This is my attempt to mock it with "with"

    
    it("should submit to server", function() {
    
            var localContext = {
                "window": {
                    arguments: ["http://localhost"]
                }
    
            }
    
            with(localContext);
    
    

    But I still get this error TypeError: Cannot read property '0' of undefined, it's like when the test is run window.arguments[0] gets wiped out with the real window, because if I do

    window.arguments[0]

    inside the test, it prints out "http://localhost" correctly. but when it comes to submit() method it shows the error that window.argument is undefined.

  • toy
    toy over 12 years
    Thanks for the reply, so I can't mock that up?
  • chetan1507
    chetan1507 over 4 years
    This is only relevant for angular related use cases.