Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
744 views
in Technique[技术] by (71.8m points)

javascript - jasmine mock window object

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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']});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...