-->

How to unit test javascript function that calls ge

2019-07-22 04:47发布

问题:

I've been struggling with unit test for 2 days now and there is something I can't achieve regarding async test. I'm new to unit test and I don't understand why this doesn't work.

I have a file login.js that calls a $.getJSON(url, data, function) and returns a string with the status of login ("success" or "fail"). The call to $.getJSON uses mockjax to get the data (it wraps an ajax call).

The login function works ok, when called from a test webpage using jQuery click event. But now I'm trying to run headless test using Qunit and PhantomJS.

It seems the problem is that the test is not waiting for the $.getJSON call to get the result (even when using a timeout). Any clues? Here is the code.

login.js

var login = function(user, pass){
    $.getJSON("loginURL", {"user":user, "pass":pass}, function(response){
       if(response.status === "success"){
           //do something
           return "success";
       } 
       else{
           //do something else
           return "fail";
       } 
    });
};

test.js

test("Test login", function(){
    var user = "user1", pass = "pass1";
    var done = assert.async();
    var result = login(user, pass);
    setTimeout(function(){
    assert.equal(result, "success", "expect login succeded");
    done();
    },1000);
});

In the test result I get:

Expected: "success"

Result: undefined

回答1:

Your login function should be asynchronous, because its result depends on a response from server.

So let's rewrite the function like this:

function login(user, pass, done) {
    $.getJSON(..., function (res) {
        done(res.status == 'success')
    })
}

Then you can test like this (assuming mocha):

describe('...', function () {
    it('login()', function (done) {
        login('user', 'pw', function (isLoggedIn) {
            assert(isLoggedIn)
            done()
        })
    })
})


回答2:

After rewrite my login function as @ayanami suggested the code works smoothly and it looks like this:

login.js

var login = function(form, cb){
   $.getJSON("loginURL", {"user":user, "pass":pass}, function(response){
        if(response.status === "success"){
            //do something
        }
        else{
            //do something else
        }
       cb(response.status);
    });
};

test.js (qunit)

test( "Testing login", function( assert ) {
    var done = assert.async();
    var cb = function(param){
                assert.equal(param,"success", "Expect getJSON/login to success");
                done();
            };
    login(user, pass,cb);
});