각도에서의 $window.location.replace를 조롱하는 방법JS 유닛 테스트?
다음과 같은 서비스를 받고 있습니다.
angular.module("services")
.factory("whatever", function($window) {
return {
redirect: function() {
$window.location.replace("http://www.whatever.com");
}
};
});
조롱하는 방법$window
object in unit test는 테스트 실행 시 페이지가 새로고침되지 않도록 합니다.
나는 그것을 사용해봤어요.
spyOn($window.location, 'replace').andReturn(true);
하지만 효과가 없었습니다(아직도)."Some of your tests did a full page reload!"
에러) 및
$provide.value('$window', {location: {replace: jasmine.createSpy()}})
에러가 발생하고 있었습니다(Error: [ng:areq] Argument 'fn' is not a function, got Object
스택 트레이스가 각진 자신의 소스만을 가리키고 있기 때문에 그다지 도움이 되지 않았습니다.
Chrome(다른 브라우저에서는 테스트하지 않음)에서는 location.replace가 읽기 전용이므로 spyOn에서 교체할 수 없습니다.
$provide.value
작동해야 합니다.당신 코드 어딘가에 뭔가 잘못된 게 틀림없어요
여기 작업 단위 테스트가 있습니다.
describe('whatever', function() {
var $window, whatever;
beforeEach(module('services'));
beforeEach(function() {
$window = {location: { replace: jasmine.createSpy()} };
module(function($provide) {
$provide.value('$window', $window);
});
inject(function($injector) {
whatever = $injector.get('whatever');
});
});
it('replace redirects to http://www.whatever.com', function() {
whatever.redirect();
expect($window.location.replace).toHaveBeenCalledWith('http://www.whatever.com');
});
});
저는 더 쉽지만 덜 우아한 해결책을 택할 것입니다.$window.location에 대한 래퍼를 작성하고 있습니다.이 래퍼는 모킹할 수 있습니다.당신의 코드에 관해서는 $window(여기에서는 당신의 실제 기능이 더 복잡하다고 가정합니다)가 아니라 whattery.redirect 함수를 비웃는 것입니다.
결국엔 다음과 같은 결과가...
angular.module("services")
.factory("whatever", function($window) {
return {
do_stuff_that_redirects: function() {
lots of code;
this.redirect("http://www.whatever.com");
maybe_more_code_maybe_not;
},
redirect: function(url) {
$window.location.replace(url);
}
};
});
리다이렉트 메서드를 직접 조롱할 수 있습니다.또한 코드 행이1개밖에 없기 때문에 문제가 발생하지 않는다고 믿을 수 있습니다.
spyOn(whatever, 'redirect').andCallFake(function(){});
expect(whatever.redirect).toHaveBeenCalledWith('http:/my.expected/url');
이것으로 충분하며, 호출된 URL을 검증할 수 있습니다.
당신에게 도움이 될 만한 다른 방법을 제시하겠습니다.궁극적으로 사용자를 리다이렉트하는 컨트롤러의 '액션'을 유닛에서 테스트하는 동안 동일한 문제에 직면했습니다(전체 페이지 로드, 그러나 더 큰 웹 사이트/애플리케이션의 다른 페이지로 이동).콘텍스트를 제공하기 위해 컨트롤러는 AJAX 요구를 실행합니다.응답이 정상일 경우 $window.location.replace()를 통해 사용자를 다른 페이지로 리다이렉트합니다.
$http.post('save', data)
.success(function(responseData, status, headers, config) {
if(responseData.redirect) {
$window.location.replace(responseData.redirect);
}
})
.error(function(responseData, status, headers, config) {
console.error("ERROR while trying to create the Event!!");
});
이 컨트롤러 기능의 테스트에서는 "Some your tests do full page reload!"라는 동일한 오류가 발생했습니다.그래서 컨트롤러 사양의 beforeEach() 함수에 $window 서비스를 mockout하기 위해 다음 사항을 추가했습니다.
mockWindow = { location: { replace: function(url) { console.log('redirecting to: ' + url); } } };
eventCtrl = $controller('EventCtrl', { $scope: scope, $window: mockWindow });
물론 이 솔루션에서는 replace 함수가 예상된 인수로 호출되었는지(정확하게) 확인할 수 없지만, 지금은 별로 신경 쓰지 않습니다.도움이 됐으면 좋겠다.
제 생각에 당신이 원하는 것은 $location 서비스를 이용하는 것입니다.$window.location
이 기능에 대해 설명하는 페이지도 있습니다.http://docs.angularjs.org/guide/dev_guide.services.$location
이것을 사용하면 테스트에서 $location 서비스의 stubbed 버전을 사용하는 것이 매우 간단할 것입니다.
$location.path('/someNewPath');
$location.replace(); // 또는 $location.path('/some New Path').replace();
언급URL : https://stackoverflow.com/questions/20252382/how-to-mock-window-location-replace-in-angularjs-unit-test
'source' 카테고리의 다른 글
ngRepeat inside angularjs 디렉티브의 $index (0) | 2023.03.18 |
---|---|
URL이 있는 JavaScript를 사용하여 HTML 코드 가져오기 (0) | 2023.03.18 |
봄 JUnit:자동 배선 구성 요소에서 자동 배선 구성 요소를 모의하는 방법 (0) | 2023.03.18 |
JavaScript 개체를 통해 루프하는 모범 사례 (0) | 2023.03.18 |
리액트/타이프스크립트의 소품으로 열거를 사용하는 방법 (0) | 2023.03.18 |