2013-07-24 21 views
28

Çok fazla okuduktan sonra, bir AngularJS kontrol cihazından web servisini çağırmanın önerilen yolunun bir fabrika kullanmak ve bundan bir söz vermek olduğunu görüyoruz.

Burada örnek API'yi çağıran basit bir fabrikam var.

myApp.factory('MyFactory', ['$http',function($http) { 
var people = { 
     requestPeople: function(x) { 
      var url = 'js/test.json'; 
      return $http.get(url); 
     } 
    }; 
return people; 
}]); 

Ve bu kontrolörün

myApp.controller('MyCtrl1', ['$scope', 'MyFactory', function ($scope, MyFactory) { 
     MyFactory.requestPeople(22).then(function(result) { 
      $scope.peopleList = result; 
     }); 
}]); 

iyi çalışıyor, ben then çağrıldığında geçirilen result alay edebilmek istiyorum bunu diyoruz nasıl. Mümkün mü?

Şimdiye kadar yaptığım girişim hiçbir şey üretmedi.

//Fake service 
var mockService = { 
    requestPeople: function() { 
     return { 
      then: function() { 
       return {"one":"three"}; 
      } 
     } 

    } 
}; 


//Some setup 
beforeEach(module('myApp.controllers')); 
var ctrl, scope; 

beforeEach(inject(function ($rootScope, $controller) { 
    scope = $rootScope.$new(); 

    ctrl = $controller('MyCtrl1', { $scope: scope, MyFactory: mockService }); 
})); 

//Test 
it('Event Types Empty should default to false', inject(function() { 
    expect(scope.peopleList.one).toBe('three'); 
})); 

karma koşucu bu çalıştırırken alıyorum hata,

TypeError geçerli:: ('scope.peopleList.one' değerlendirirken) 'tanımsız' bir nesne değil

Bu benim girişimidir

Bu sınama, sahte verilerimle nasıl çalışır?

+0

bu konuda okumuştum ama benim denetleyicisi bir $ http almaz. Ne demek istediğini anlatabilir misin? – Mendhak

cevap

38

Buraya geldiğinizde $ httpBackend olduğunu düşünmüyorum, bütün fabrikanın $ http bağımlılığı olmadan alay edilmesini mi istiyorsunuz?

$q, özellikle Test başlığı altındaki kod örneğine bir bakın. Sorununuz kodu ile çözülmesi olabilir şuna benzer olduğunu:

'use strict'; 

describe('mocking the factory response', function() { 

    beforeEach(module('myApp.controllers')); 

    var scope, fakeFactory, controller, q, deferred; 

    //Prepare the fake factory 
    beforeEach(function() { 
     fakeFactory = { 
      requestPeople: function() { 
       deferred = q.defer(); 
       // Place the fake return object here 
       deferred.resolve({ "one": "three" }); 
       return deferred.promise; 
      } 
     }; 
     spyOn(fakeFactory, 'requestPeople').andCallThrough(); 
    }); 

    //Inject fake factory into controller 
    beforeEach(inject(function ($rootScope, $controller, $q) { 
     scope = $rootScope.$new(); 
     q = $q; 
     controller = $controller('MyCtrl1', { $scope: scope, MyFactory: fakeFactory }); 
    })); 

    it('The peopleList object is not defined yet', function() { 
     // Before $apply is called the promise hasn't resolved 
     expect(scope.peopleList).not.toBeDefined(); 
    }); 

    it('Applying the scope causes it to be defined', function() { 
     // This propagates the changes to the models 
     // This happens itself when you're on a web page, but not in a unit test framework 
     scope.$apply(); 
     expect(scope.peopleList).toBeDefined(); 
    }); 

    it('Ensure that the method was invoked', function() { 
     scope.$apply(); 
     expect(fakeFactory.requestPeople).toHaveBeenCalled(); 
    }); 

    it('Check the value returned', function() { 
     scope.$apply(); 
     expect(scope.peopleList).toBe({ "one": "three" }); 
    }); 
}); 

etrafında bazı testler nelerin eklendiğini $, ben başlayana kadar bu oynamaktan bilmiyordum gelmez geçerlidir!

Yecüc

+0

Bu mükemmel bir şekilde çalıştı. Benzer bir şeye geldim ama eksik olduğum şey defer değerinin uygun bir değer getirmesiydi ve şimdi $ scope.apply() işlevi daha mantıklı. – Mendhak

+0

Bu kodda başarı temel birimleri testleri gerçekleştirdim. Ancak, "denetleyici" sözdizimine geçme, testi geçmek için nasıl değiştirileceği açık değildir. Sorun, '' MyCtrl1 foo '' kullanmak problemdir. 'Not.toBeDefined' testleri bile 'TypeError: undefined bir işlev değil 'ile başarısız olur. –

+1

Burada 'spyOn' ifadesinin önemi nedir? Test özelliklerini kaldırdım ve test hala başarılı bir şekilde geçti. – Aakash

İlgili konular