AngularJs에서 개인 메서드를 사용하여 테스트 가능한 컨트롤러를 작성하는 방법은 무엇입니까?
네, 그래서 저는 오랫동안 어떤 문제에 부딪혀왔기 때문에 다른 지역사회의 의견을 듣고 싶습니다.
먼저 추상 컨트롤러에 대해 살펴보겠습니다.
function Ctrl($scope, anyService) {
$scope.field = "field";
$scope.whenClicked = function() {
util();
};
function util() {
anyService.doSmth();
}
}
분명히 다음과 같은 일이 있습니다.
- 컨트롤러용 일반 발판
$scope
서비스 주입이 완료되었습니다. - 스코프에 부속된 몇 가지 필드 및 기능
- 개인 방식
util()
자, 이 수업을 유닛 테스트(재스민)에서 다루고 싶습니다.다만, (콜)을 클릭했을 때에, 확인하려고 하는 것이 문제입니다.whenClicked()
)의 몇 가지 아이템은util()
메서드가 호출됩니다.어떻게 해야 할지 모르겠어요. 왜냐하면 재스민 테스트에서는 항상 오류가 나거든요.util()
정의되지 않았거나 호출되지 않았습니다.
주의: 이 예를 수정하려는 것이 아니라 일반적인 코드 패턴 테스트에 대해 물어보는 것입니다.그러니 "정확한 오류"는 말하지 말아주세요.난 그걸 어떻게 하냐고 물어보는 거지, 이걸 어떻게 고치냐고 물어보는 게 아니야.
저는 이 문제를 해결하기 위해 여러 가지 방법을 시도해 왔습니다.
- 분명히 나는 사용할 수 없다
$scope
이 오브젝트에 이 기능이 연결되어 있지 않기 때문에 유닛테스트에서 (보통 메시지로 끝납니다)Expected spy but got undefined
또는 유사) - 이 기능을 컨트롤러 오브젝트에 연결하려고 했습니다.
Ctrl.util = util;
그런 다음 이런 모크들을 검증하고Ctrl.util = jasmine.createSpy()
그러나 이 경우에는Ctrl.util
호출되지 않기 때문에 테스트는 실패합니다. - 나는 변하려고 했다
util()
애착을 가지다this
반대와 조롱Ctrl.util
다시 말하지만, 운이 없다
글쎄요, 저는 이 문제를 해결할 방법을 찾을 수 없습니다. JS 닌자의 도움을 받을 수 있을 것 같습니다. 바이올린이 작동하면 완벽할 것 같습니다.
제공한 컨트롤러 함수는 Angular에 의해 생성자로 사용됩니다. 어느 시점에서 이 함수는 다음과 같이 호출됩니다.new
실제 컨트롤러 인스턴스를 만듭니다.$scope에 노출되지 않지만 스파이/스텁/모킹에 사용할 수 있는 함수를 컨트롤러 오브젝트에 꼭 포함시켜야 할 경우 다음 URL에 첨부할 수 있습니다.this
.
function Ctrl($scope, anyService) {
$scope.field = "field";
$scope.whenClicked = function() {
util();
};
this.util = function() {
anyService.doSmth();
}
}
지금 전화할 때var ctrl = new Ctrl(...)
또는 Angular를 사용합니다.$controller
를 취득하기 위한 서비스Ctrl
예를 들어 반환되는 오브젝트에는util
기능.
다음 접근방식을 보실 수 있습니다.http://jsfiddle.net/yianisn/8P9Mv/
스코프에 이름을 붙이는 것은 공해입니다.이 논리를 다른 함수로 추출하여 컨트롤러에 주입합니다.
function Ctrl($scope, util) {
$scope.field = "field";
$scope.whenClicked = function() {
util();
};
}
angular.module("foo", [])
.service("anyService", function(...){...})
.factory("util", function(anyService) {
return function() {
anyService.doSmth();
};
});
이제 Ctrl 및 "util"을 사용하여 유닛 테스트를 수행할 수 있습니다.
나는 다른 접근법으로 동참할 것이다.사적인 방법을 시험해 보면 안 돼그렇기 때문에 개인 사용자입니다.사용방법과 무관한 구현 세부 사항입니다.
예를 들어, util이 여러 곳에서 사용되었지만 다른 코드 리팩터링에 기반하여 이 한 곳에서만 호출된다는 것을 알게 되면 어떻게 될까요?왜추 기능 ?출 출? ???포함시키기만 하면 됩니다.anyService.doSmith()
$scope.whenClicked()
상기의 과 함께, 만약 여러분이 하고 있다고 한다면, 은 그것을 시험해 볼 수 있습니다.util()
프로그램 기능을 변경하지 않아도 테스트가 중단됩니다.유닛 테스트의 주요 가치 중 하나는 물건을 망가뜨리지 않고 리팩터링을 단순화하는 것입니다.그래서 물건을 망가뜨리지 않았다면 테스트는 실패하지 않았을 것입니다.
할 은 '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때'를$scope.whenClicked
라고 합니다.anyService.doSmth()
고도불불 불불불다다필요한 것은 다음과 같습니다.
spyOn(anyService,'doSmith')
scope.whenClicked();
expect(anyService.doSmith).toHaveBeenCalled();
현재의 접근방식을 포함한 답변을 추가해, 코멘트를 얻고, 이것이 좋은 해결책인지 아닌지에 대해 논의를 진행시키고 싶다고 생각하고 있습니다.
컨트롤러 기능에 프라이빗 기능을 부가하고 있습니다(따라서 공개함으로써 모킹이 가능합니다). 구문을 " "를 만들고 .self
컨트롤러 기능을 참조하는 객체. 이렇게 됩니다: ㄴ, ㄴ, ㄴ, ㄴ, ㄴ ㄴ이 되다.
function Ctrl($scope, anyService) {
$scope.field = "field";
$scope.whenClicked = function() {
self.util();
};
var self = Ctrl; // For the sake of syntax simplicity only
self.util = function() {
anyService.doSmth();
};
}
다음으로 유닛 테스트에서 다음을 사용할 수 있습니다.
Ctrl.util = jasmine.createSpy("util()");
expect(Ctrl.util).toHaveBeenCalled();
저는 여전히 이것이 별로 마음에 들지 않지만, 이것이 가장 간단한 방법이라고 생각합니다.누군가 더 나은 방법을 찾길 바란다.
언급URL : https://stackoverflow.com/questions/15966989/how-to-write-testable-controllers-with-private-methods-in-angularjs
'code' 카테고리의 다른 글
ui-module:뷰 템플릿이 없는 루트 (0) | 2023.03.09 |
---|---|
TypeScript 코멘트의 구문은 어디에 기재되어 있습니까? (0) | 2023.03.09 |
플라스크를 사용하여 오리진 간 자원 공유 해결 (0) | 2023.03.09 |
ReactJ에서는 동기 호출 시 setState가 다르게 동작하는 이유는 무엇입니까? (0) | 2023.03.04 |
AngularJS HTML을 동적으로 추가하고 컨트롤러에 바인드하는 방법 (0) | 2023.03.04 |