18

Mamy niewiele metod w sterowniku kątowym, które nie znajdują się w zmiennej zasięgu.W jaki sposób możemy przetestować metody kontrolerów kątowych innych niż zakres?

Czy ktoś wie, w jaki sposób możemy wykonać lub wywołać te metody w testach Jasmine?

Oto główny kod.

var testController = TestModule.controller('testController', function($scope, testService) 
{ 

function handleSuccessOfAPI(data) { 
    if (angular.isObject(data)) 
    { 
     $scope.testData = data; 
    } 
} 

function handleFailureOfAPI(status) { 
    console.log("handleFailureOfAPIexecuted :: status :: "+status); 
} 

// this is controller initialize function. 
function init() { 
    $scope.testData = null; 

    // partial URL 
    $scope.strPartialTestURL = "partials/testView.html; 

    // send test http request 
    testService.getTestDataFromServer('testURI', handleSuccessOfAPI, handleFailureOfAPI); 
} 

init(); 
} 

Teraz w moim teście jaśmin, mijamy „handleSuccessOfAPI” i „handleFailureOfAPI” metody, ale są niezdefiniowane.

Oto kod testu jaśminu.

describe('Unit Test :: Test Controller', function() { 
var scope; 
var testController; 

var httpBackend; 
var testService; 


beforeEach(function() { 
    module('test-angular-angular'); 

    inject(function($httpBackend, _testService_, $controller, $rootScope) { 

     httpBackend = $httpBackend; 
     testService= _testService_; 

     scope = $rootScope.$new(); 
     testController= $controller('testController', { $scope: scope, testService: testService}); 
      }); 
}); 

afterEach(function() { 
     httpBackend.verifyNoOutstandingExpectation(); 
     httpBackend.verifyNoOutstandingRequest(); 
    }); 

it('Test controller data', function(){ 
    var URL = 'test server url'; 

    // set up some data for the http call to return and test later. 
    var returnData = { excited: true }; 

    // create expectation 
    httpBackend.expectGET(URL).respond(200, returnData); 

    // make the call. 
    testService.getTestDataFromServer(URL , handleSuccessOfAPI, handleFailureOfAPI); 

    $scope.$apply(function() { 
     $scope.runTest(); 
    }); 

    // flush the backend to "execute" the request to do the expectedGET assertion. 
    httpBackend.flush(); 

    // check the result. 
    // (after Angular 1.2.5: be sure to use `toEqual` and not `toBe` 
    // as the object will be a copy and not the same instance.) 
    expect(scope.testData).not.toBe(null); 
}); 
}); 

Odpowiedz

8

Nie będziesz mieć dostępu do tych funkcji. Po zdefiniowaniu nazwie funkcji JS to samo jakbyś był powiedzieć

var handleSuccessOfAPI = function(){}; 

W tym przypadku byłoby to dość oczywiste, aby zobaczyć, że zmienna jest tylko w zakresie w bloku i nie ma odniesienia zewnętrzne do niego z kontrolera owijającego.

Każda funkcja, którą można nazwać dyskretnie (a zatem przetestowana) będzie dostępna w $ scope kontrolera.

+2

Prawidłowo. Co więcej, nie powinniśmy testować funkcji prywatnych. Ogólnie rzecz biorąc, 'init()' jest testowane jednostkowo z próbnymi danymi, które zapewniają, że 'handleSuccessOfAPI' lub' handleFailureOfAPI 'jest wywoływany. Wyśmiewane obiekty/dane powinny kierować ścieżką wykonania. – dmahapatro

+0

Widzę $ scope jako czyniącą funkcję/zmienną publiczną (porównując ją do czegoś takiego jak Java). Nie jestem zbyt zaznajomiony z testowaniem jednostkowym w Javie, ale czy "nie testuję funkcji prywatnych", co zwykle robisz w Javie? – Chris

+0

Chris, mam również ograniczone doświadczenie w pisaniu testów, napisałem kilka testów JUnit, ale w żadnym wypadku nie jestem ekspertem od testowania. Wyobrażam sobie, ponieważ funkcje prywatne nie są ujawnione, gdy tworzysz instancję obiektu, w którym wciąż jesteś pod tym samym ograniczeniem, że możesz testować tylko te rzeczy, które są publicznie dostępne. Myślę, że ostatecznie ma to sens, ponieważ naprawdę interesujesz się fragmentem kodu wykonującym zadanie w rodzaju czarnej skrzynki podczas pisania testu, to znaczy, jeśli dostarczę x, oczekuję y, ale szczegóły implementacji nie są niepokój. – shaunhusain

9

Wiem, że to stary przypadek, ale tutaj jest rozwiązanie, którego używam.

Użyj 'this' od kontrolera

.controller('newController',['$scope',function($scope){ 
    var $this = this; 
    $this.testMe = function(val){ 
     $scope.myVal = parseInt(val)+1; 
    } 
}]); 

Tutaj jest test:

describe('newDir', function(){ 
var svc, 
    $rootScope, 
    $scope, 
    $controller, 
    ctrl; 


beforeEach(function() { 
    module('myMod'); 
}); 

beforeEach(function() { 
    inject(function (_$controller_,_$rootScope_) { 

     $controller = _$controller_; 
     $rootScope = _$rootScope_; 
     $compile = _$compile_; 
     $scope = $rootScope.$new(); 
     ctrl = $controller('newController', {'$rootScope': $rootScope, '$scope': $scope }); 
    }); 
}); 

it('testMe inc number', function() { 

    ctrl.testMe(10) 
    expect($scope.myVal).toEqual(11); 
}); 

});

Full Code Example

+0

Czy jest jakiś powód, dla którego używasz '$ this' lub po prostu dlatego, że nie lubisz używać zmiennych takich jak' self'? – svassr

+0

Pytasz, dlaczego nazwałem moją zmienną "$ this" zamiast nazywać ją "self"? Nie ma powodu dla mojego wyboru w nazwach zmiennych. "Self" może sprawić, że kod będzie łatwiejszy do odczytania. – tmc

+0

Tak, to było rzeczywiście pytanie Dzięki – svassr