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

allUsers は常に未定義であるため、getPosition メソッドが問題です (明らかな場合があります)。ここにあるのはまだ別の試みです。いくつかの方法を試しました。問題は、最初に Users.getUsers がどのように呼び出されるかだと思いますが、外側と内側の変数を使用しているかどうかもわかりません。

4

3 に答える 3

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 呼び出しは、返してほしいものを何でも返すようになります。これにより、失敗や予期しないデータなどのテストをモックアウトすることもできます。いくつかの異なる結果をテストしたいが、結果ごとに JSON ファイルが必要ない場合に役立ちます。

Sorta-edit - これでテスト ケースは修正されますが、おそらくコードは修正されません。私のお勧めは、ajax コール リターンに依存するときはいつでも、呼び出しているメソッドに「callback」引数があることを確認することです。例えば:

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 に答える
1

データを埋めるためのあなたのアプローチ は、jquery の ajax 呼び出しにallUsers欠陥があるため、すべての呼び出しは何も返されず、後で jquery ajax の成功関数が呼び出されたときに埋められます。
users.getAllUsersallUsers

于 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 に答える