앵귤러에 모의 주입JS 서비스
나는 Angular를 가지고 있다.JS서비스가 작성되어 유닛테스트를 하고 싶습니다.
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) {
this.something = function() {
// Do something with the injected services
};
return this;
});
내 app.js 파일에는 다음이 등록되어 있습니다.
angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)
DI가 다음과 같이 동작하고 있는지 테스트할 수 있습니다.
describe("Using the DI framework", function() {
beforeEach(module('fooServiceProvider'));
beforeEach(module('barServiceProvider'));
beforeEach(module('myServiceProvder'));
var service;
beforeEach(inject(function(fooService, barService, myService) {
service=myService;
}));
it("can be instantiated", function() {
expect(service).not.toBeNull();
});
});
이것은 DI 프레임워크로 서비스를 만들 수 있다는 것을 증명해 주었지만, 다음에는 서비스 유닛 테스트를 하고 싶다.즉, 주입된 오브젝트를 제외한다.
이걸 어떻게 해야 하죠?
모듈에 모의 객체를 넣으려고 했습니다.
beforeEach(module(mockNavigationService));
서비스 정의를 다음과 같이 다시 작성합니다.
function MyService(http, fooService, barService) {
this.somthing = function() {
// Do something with the injected services
};
});
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })
그러나 후자는 DI에 의해 만들어지는 서비스를 모두 중지하는 것으로 보입니다.
내 유닛 테스트를 위해 주입된 서비스를 어떻게 조롱할 수 있는지 아는 사람?
감사해요.
데이빗
다음을 사용하여 서비스에 Mock을 주입할 수 있습니다.$provide.
종속성이 getSomething이라는 메서드를 가진 다음 서비스가 있는 경우:
angular.module('myModule', [])
.factory('myService', function (myDependency) {
return {
useDependency: function () {
return myDependency.getSomething();
}
};
});
다음과 같이 myDependency 모의 버전을 삽입할 수 있습니다.
describe('Service: myService', function () {
var mockDependency;
beforeEach(module('myModule'));
beforeEach(function () {
mockDependency = {
getSomething: function () {
return 'mockReturnValue';
}
};
module(function ($provide) {
$provide.value('myDependency', mockDependency);
});
});
it('should return value from mock dependency', inject(function (myService) {
expect(myService.useDependency()).toBe('mockReturnValue');
}));
});
에의 콜에 의해,$provide.value실제로 myDependency를 명시적으로 삽입할 필요는 없습니다.my Service 주입 중 후드 아래에서 발생합니다.여기서 mockDependency를 셋업할 때 스파이일 수도 있습니다.
그 멋진 비디오로 연결시켜준 충성스런 브라운에게 감사한다.
제가 보기에는 서비스 자체를 조롱할 필요는 없습니다.서비스의 기능을 조롱하기만 하면 됩니다.이렇게 하면 앱 전체에서처럼 실제 서비스를 각도로 주입할 수 있습니다.그런 다음 필요에 따라 Jasmine의 기능을 사용하여 서비스의 기능을 조롱합니다.spyOn기능.
서비스 자체가 함수이며 사용할 수 있는 객체가 아닌 경우spyOn다른 방법이 있어요난 이걸 해야 했고, 나에게 꽤 잘 맞는 것을 찾아냈다.함수인 Angular 서비스를 조롱하는 방법을 참조하십시오.
Angular와 Jasmine에서 조롱 의존성을 쉽게 만드는 또 다른 옵션은 QuickMock을 사용하는 것입니다.GitHub에서 찾을 수 있으며 재사용 가능한 간단한 모크를 만들 수 있습니다.아래 링크를 통해 GitHub에서 복제할 수 있습니다.README은 매우 자명하지만, 미래에 다른 사람들에게 도움이 될 수 있기를 바랍니다.
https://github.com/tennisgent/QuickMock
describe('NotificationService', function () {
var notificationService;
beforeEach(function(){
notificationService = QuickMock({
providerName: 'NotificationService', // the provider we wish to test
moduleName: 'QuickMockDemo', // the module that contains our provider
mockModules: ['QuickMockDemoMocks'] // module(s) that contains mocks for our provider's dependencies
});
});
....
위의 보일러 플레이트를 모두 자동으로 관리하므로 모든 테스트에서 모의 주입 코드를 모두 작성할 필요가 없습니다.도움이 됐으면 좋겠다.
John Galambos의 답변에 덧붙여, 특정의 서비스 방법을 시험해 보고 싶은 경우는, 다음과 같이 실시할 수 있습니다.
describe('Service: myService', function () {
var mockDependency;
beforeEach(module('myModule'));
beforeEach(module(function ($provide, myDependencyProvider) {
// Get an instance of the real service, then modify specific functions
mockDependency = myDependencyProvider.$get();
mockDependency.getSomething = function() { return 'mockReturnValue'; };
$provide.value('myDependency', mockDependency);
});
it('should return value from mock dependency', inject(function (myService) {
expect(myService.useDependency()).toBe('mockReturnValue');
}));
});
컨트롤러가 다음과 같은 종속성을 받아들이도록 기술되어 있는 경우:
app.controller("SomeController", ["$scope", "someDependency", function ($scope, someDependency) {
someDependency.someFunction();
}]);
가짜를 수 someDependency이런 재스민 테스트에서요.
describe("Some Controller", function () {
beforeEach(module("app"));
it("should call someMethod on someDependency", inject(function ($rootScope, $controller) {
// make a fake SomeDependency object
var someDependency = {
someFunction: function () { }
};
spyOn(someDependency, "someFunction");
// this instantiates SomeController, using the passed in object to resolve dependencies
controller("SomeController", { $scope: scope, someDependency: someDependency });
expect(someDependency.someFunction).toHaveBeenCalled();
}));
});
나는 최근 Angular에서 모의 테스트를 해야 하는 ngInvedTesting을 출시했다.JS는 훨씬 쉬워.
fooService 및 barService 종속성을 조롱하여 myApp 모듈에서 'myService'를 테스트하려면 Jasmine 테스트에서 다음을 수행합니다.
beforeEach(ModuleBuilder
.forModule('myApp')
.serviceWithMocksFor('myService', 'fooService', 'barService')
.build());
ng Improved Testing에 대한 자세한 내용은 소개 블로그 포스트를 참조하십시오.http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/
오래된 질문인 것은 알지만 다른 쉬운 방법이 있습니다.모크 작성과 삽입된 원래 기능을 비활성화할 수 있습니다.모든 방법으로 spyOn을 사용하여 실행할 수 있습니다.아래의 코드를 참조해 주세요.
var mockInjectedProvider;
beforeEach(function () {
module('myModule');
});
beforeEach(inject(function (_injected_) {
mockInjectedProvider = mock(_injected_);
});
beforeEach(inject(function (_base_) {
baseProvider = _base_;
}));
it("injectedProvider should be mocked", function () {
mockInjectedProvider.myFunc.andReturn('testvalue');
var resultFromMockedProvider = baseProvider.executeMyFuncFromInjected();
expect(resultFromMockedProvider).toEqual('testvalue');
});
//mock all service methods
function mock(angularServiceToMock) {
for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) {
spyOn(angularServiceToMock,Object.getOwnPropertyNames(angularServiceToMock)[i]);
}
return angularServiceToMock;
}
언급URL : https://stackoverflow.com/questions/14773269/injecting-a-mock-into-an-angularjs-service
'source' 카테고리의 다른 글
| 셀레늄을 어떻게 아약스 반응을 기다리죠? (0) | 2023.03.21 |
|---|---|
| $http.get은 Access-Control-Allow-Origin에서 허용되지 않지만 $.ajax는 허용됩니다. (0) | 2023.03.21 |
| RESTful 원칙을 위반하지 않고 Angular에서 인증 및 인가를 위한 베스트 프랙티스 (0) | 2023.03.21 |
| Angularjs ng-click: 이 데이터를 얻는 방법 (0) | 2023.03.21 |
| Jackson의 @JsonSubTypes는 다형성 디시리얼라이제이션에 여전히 필요한가요? (0) | 2023.03.21 |