1

我正在创建一个用户集合,该集合能够在其中获取单个用户。这将用于从另一个系统进行匹配,所以我希望加载用户一次,然后能够在以后进行微调/匹配。但是,我在从内部方法访问外部用户集合时遇到问题。

function Users(){

    var allUsers;

    this.getUsers = function () {
        // ajax to that Jasmine behaves    
        $.ajax({
            url: '../app/data/jira_users.json',
            async: false,
            dataType: 'json',
            success: function(data) {
                allUsers = data;
            }
        });
        return allUsers;
    };

    this.SingleUser = function (name) {
        var rate = 0.0;
        var position;

        this.getRate = function () {
            if(position === undefined){
                console.log('>>info: getting user position to then find rate');
                this.getPosition();
            }

            $.ajax({
                url: '../app/data/rates.json',
                async: false,
                dataType: 'json',
                success: function(data) {
                    rate = data[position];
                }
            });
            return rate;
        };

        this.getPosition = function () {
            console.log(allUsers);
            //position = allUsers[name];
            return position;
        };

        //set name prop for use later I guess.
        this.name = name;
    };
}

以及开始这一切的测试:

it("get single user's position", function(){
    var users = new Users();
    var someone = new users.SingleUser('bgrimes');
    var position = someone.getPosition();
    expect(position).not.toBeUndefined();
    expect(position).toEqual('mgr');
});

getPosition 方法是问题(这可能很明显),因为 allUsers 始终未定义。我在这里是另一种尝试,我尝试了几种方法。我认为问题是如何开始调用 Users.getUsers,但我也不确定我使用的外部和内部变量是否正确。

4

3 回答 3

1

您填充数据的allUsers方法有缺陷
jquery 中的 ajax 调用是异步的,因此每次调用users.getAllUsers都将返回没有任何内容,当稍后调用 jquery ajax 的成功函数时,allUsers将被填充

于 2012-11-25T17:09:01.850 回答
1

this.getUsers()不会工作。它的返回与allUsers获取数据的 ajax 请求无关,因为 ajax 是异步的。与 相同getRate()

您必须使用回调方法,getUsers()使用回调引用进行调用,当 ajax 请求完成时,它将数据传递给回调函数。

就像是:

this.getUsers = function (callback) {
    // ajax to that Jasmine behaves    
    $.ajax({
        url: '../app/data/jira_users.json',
        async: false,
        dataType: 'json',
        success: function(data) {
            callback(data);
        }
    });
};

电话将按照以下方式进行:

var user_data = null;
Users.getUsers(function(data) {
    user_data = data;
});
于 2012-11-25T17:09:09.533 回答
1

尽管其他人是正确的,因为当您输入它时这将不起作用,但我看到用例是一个 jasmine 测试用例。因此,有一种方法可以使您的测试成功。通过执行以下操作,您无需实际运行任何类型的服务器来进行测试。

var dataThatYouWouldExpectFromServer = {
    bgrimes: {
        username: 'bgrimes',
        show: 'chuck',
        position: 'mgr'
    }
};

it("get single user's position", function(){
    var users = new Users();
    spyOn($, 'ajax').andCallFake(function (ajaxOptions) {
        ajaxOptions.success(dataThatYouWouldExpectFromServer);
    });
    users.getUsers();
    var someone = new users.SingleUser('bgrimes');
    var position = someone.getPosition();
    expect(position).not.toBeUndefined();
    expect(position).toEqual('mgr');
});

这将使 ajax 调用返回您希望它返回的任何内容,这还允许您模拟失败、意外数据等的测试。您可以随时将“dataThatYouWouldExpectFromServer”设置为您想要的任何内容。这可以在您想要测试几个不同的结果但不希望每个结果都有一个 JSON 文件的情况下提供帮助。

Sorta-edit - 这将修复测试用例,但可能不会修复代码。我的建议是,每当您依赖 ajax 调用返回时,请确保您调用的方法具有“回调”参数。例如:

var users = new Users();
users.getUsers(function () {
    //continue doing stuff
});

您可以嵌套它们,或者您可以(最好)创建回调,然后将它们用作彼此的参数。

var users = new Users(), currentUser;

var showUserRate = function () {
    //show his rate
    //this won't require a callback because we know it's loaded.
    var rate = currentUser.getRate(); 
}

var usersLoaded = function () {
    //going to load up the user 'bgrimes'
    currentUser = new users.SingleUser('bgrimes');
    currentUser.getRate(showUserRate);
}

users.getUsers(usersLoaded);
于 2012-11-25T17:18:01.287 回答