2016-07-01 21 views
0

コントローラの$ scopeオブジェクトをテストするにはどうすればよいですか?

添付された実際のデータを取得できましたか?

私のテストは以下のように設定されていますが、myScopeundefinedです。

'use strict'; 

describe('myApp.view1 module', function() { 
var $httpBackend, $rootScope, createController, jsonHandler; 
beforeEach(module('myApp.view1')); 


    describe('view1 controller', function(){ 

    beforeEach(inject(function($rootScope, $controller, $injector) { 
     // Set up the mock http service responses 
     $httpBackend = $injector.get('$httpBackend'); 
     // backend definition common for all tests 
     $httpBackend.when('GET', 'view1/quizzes.json') 
        .respond({data: '[XXX,XXX,XXX]'}); 
     // Get hold of a scope (i.e. the root scope) 
     $rootScope = $injector.get('$rootScope'); 
     // The $controller service is used to create instances of controllers 
     var $controller = $injector.get('$controller'); 

     var myScope = $rootScope.$new() 

     createController = function() { 
      return $controller('View1Ctrl', {'$scope' : myScope }); 
     }; 
     var controller = createController(); 

    })); 

    it('should get the json files', function(){ 
     $httpBackend.expectGET('/view1/quizzes.json'); 
    }); 

    it('should get the json files', function(){ 
     expect(myScope).toBe("words"); 
    }); 
    }); 
}); 

コントローラ:

myApp.controller('View1Ctrl', [ 

    '$scope', 
    '$http', 

    function($scope, $http) { 

    $http.get('view1/quizzes.json') 
    .then(function(res){ 
     $scope.quizzes = res.data.quizzes 
    }) 
    .then(function(){ 
     $http.get('view1/questions.json') 
     .then(function(res){ 
     $scope.questions = res.data.questions 
     }) 
     .then(function(){ 
     $scope.quiz = [ [], [], [], [], [] ] 

     _($scope.questions).forEach(function(qu){ 
      _($scope.quizzes).forEach(function(quiz){ 
      if (_.includes($scope.quizzes[(quiz.id - 1)].question_ids, qu.id)){ 
       $scope.quiz[(quiz.id - 1)].push(qu) 
      } 
      }) 
     }) 
     }) 
     .then(function(){ 
     // console.log($scope.quiz) 
     }) 
    }); 
    } 
]); 
+0

ここで、「myScope」の値をログに記録していますか?なぜ、$ injector.get()を使用して、関数に既に注入されているサービスを取得していますか? –

+0

@JBNizet私は別のテストでそれを記録していましたが、それは唯一のものでしたので、私はそこに追加しませんでした。私はひどく混乱しているし、何をしているのか分からないので、おそらく$ injector.get()を使用しています。ドキュメントはうまくいきません。/ – IAmAkittycatAMA

+0

myScopeはbeforeEachに渡される関数のローカル変数です。したがって、それはその機能でのみ定義されています。それを渡された関数で定義したい場合は、$ httpBackend、$ rootScopeなどと同じレベルで宣言する必要があります。 –

答えて

1

OK。まず、混乱を少しきれいにして始めましょう。インジェクションを使用して注入できるため、$ injectorを使用してサービスにアクセスする必要はありません。

また、モジュール全体に対して1つのテストを行う必要もありません。あなたのテストはコントローラをテストするだけです。バックエンドとの最初のやりとりをテストする例を示します。

describe('view1 controller', function() { 
    // declare the variables that need to be used in all tests 

    // the $scope contains the data and functions we want to test 
    var $scope; 

    // the $httpBackend service allows mocking the http... backend 
    var $httpBackend; 

    // the $controller service allows instantiating our controller 
    var $controller; 

    // load the module containing the component I want to test 
    beforeEach(module('myApp.view1')); 

    // prepare the tests. Use inject to access the services we need. 
    // To avoid a name clash with the variables defined above, we can 
    // enclose the actual service names into underscores 
    beforeEach(inject(function($rootScope, _$httpBackend_, _$controller_) { 
    // initialize our variables 
    $httpBackend = _$httpBackend_; 
    $controller = _$controller_; 

    // create a scope and initialize our $scope variable with it 
    $scope = $rootScope.$new(); 
    })); 

    // we need to be able to instantiate our controller in our tests. Let's 
    // define a function that does that 
    function createController() { 

    // we initialize the controller with the scope we have created sooner 
    // so, the scope the controller receives as argument is our scope 
    // the controller will populate the scope, and we can test it has 
    // populated it correctly 
    $controller('View1Ctrl', { $scope: $scope }); 
    } 

    // now let's write a simple test. The controller, when instantiated, 
    // should use $http to load view1/quizzes.json, and, once it gets 
    // the response, it should populate $scope.quizzes with the quizzes 
    // attribute of the JSON received as response 
    it('should populate the quizzes from the backend', function() { 

    // we first need to tell our fake backend: you should receive a 
    // request, and when you do, you should return this response 

    var data = { 
     quizzes: ['hello world'] 
    }; 

    $httpBackend.expectGET('view1/quizzes.json').respond(data); 

    // now we will create our controller. The controller should send 
    // a http request to get the quizzes. If it indeed does correctly, 
    // the fake backend will return the above data **when we tell it to 
    // do it**. 

    createController(); 

    // Now, the controller has sent the request. But it hasn't received 
    // the response yet. Let's send the response. 
    $httpBackend.flush(); 

    // now, the controller should have received the response, and should 
    // thus have extracted the quizzes from it and populated 
    // $scope.quizzes with them 
    expect($scope.quizzes).toEqual(data.quizzes); 
    }); 
}); 
+0

'$ httpBackend.expectGET( 'view1/questions.json')。respond(data);'を追加する必要もありました。 'エラー:予期せぬリクエスト:GET view1/questions.json期待どおりのリクエストがありません ' – IAmAkittycatAMA

+0

はい。私はちょうどコントローラが私の例でクイズを要求したと仮定しました。しかし、あなたはその原則を理解しているようです。おめでとう。 –

関連する問題