2012-11-25 74 views
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,但我也不确定我是否使用外部和内部变量是正确的。

+1

欢迎来到**异步**的美妙世界!你不能那样做。 – SLaks

+0

是的,我试图让这个操作更少异步。失败。谢谢。 – BryanGrimes

回答

1

虽然别人都在这个正确的,因为你拥有它打出来就不行,我看到用例是一个茉莉花测试用例。所以,有一种方法可以让你的测试成功。通过做类似下面的事情,你不需要真正运行任何类型的服务器来做你的测试。

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文件的情况。

分类编辑 - 这将修复测试用例,但可能不是代码。我的建议是,只要您依赖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); 
+0

完美,欢呼声。茉莉花测试引起了直接的头痛,但绝不是我想要的那样工作。这有助于解决问题,代码和测试。 – BryanGrimes

1

你的方法来填补allUsers的数据是有缺陷的
在jQuery的Ajax调用是异步这么users.getAllUsers每一个电话就什么也没有返回,并在以后的jQuery AJAX的成功函数被调用,然后allUsers将得到填充

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; 
}); 
+0

谢谢,回调现在不在我的“转到”模式中,显然它需要尽快完成。 – BryanGrimes