반응형
컨트롤러를 테스트하기 위한 서비스 모킹
저는 Parse Service를 가지고 있는데, 그것을 사용하는 모든 컨트롤러를 테스트하기 위해 조롱하고 싶습니다.저는 Jasmine Spy에 대해 읽고 있습니다만, 아직 불분명합니다.커스텀 서비스를 시뮬레이트하여 컨트롤러 테스트에서 사용하는 예를 들어 주실 수 있습니까?
현재 본 서비스를 사용하여 책을 삽입하는 컨트롤러가 있습니다.
BookCrossingApp.controller('AddBookCtrl', function ($scope, DataService, $location) {
$scope.registerNewBook = function (book) {
DataService.registerBook(book, function (isResult, result) {
$scope.$apply(function () {
$scope.registerResult = isResult ? "Success" : result;
});
if (isResult) {
//$scope.registerResult = "Success";
$location.path('/main');
}
else {
$scope.registerResult = "Fail!";
//$location.path('/');
}
});
};
});
서비스는 다음과 같습니다.
angular.module('DataServices', [])
/**
* Parse Service
* Use Parse.com as a back-end for the application.
*/
.factory('ParseService', function () {
var ParseService = {
name: "Parse",
registerBook: function registerBook(bookk, callback) {
var book = new Book();
book.set("title", bookk.title);
book.set("description", bookk.Description);
book.set("registrationId", bookk.RegistrationId);
var newAcl = new Parse.ACL(Parse.User.current());
newAcl.setPublicReadAccess(true);
book.setACL(newAcl);
book.save(null, {
success: function (book) {
// The object was saved successfully.
callback(true, null);
},
error: function (book, error) {
// The save failed.
// error is a Parse.Error with an error code and description.
callback(false, error);
}
});
}
};
return ParseService;
});
지금까지의 제 테스트는 다음과 같습니다.
describe('Controller: AddBookCtrl', function() {
// // load the controller's module
beforeEach(module('BookCrossingApp'));
var AddBookCtrl, scope, book;
// Initialize the controller and a mock scope
beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope;
book = {title: "fooTitle13"};
AddBookCtrl = $controller('AddBookCtrl', {
$scope: scope
});
}));
it('should call Parse Service method', function () {
//We need to get the injector from angular
var $injector = angular.injector([ 'DataServices' ]);
//We get the service from the injector that we have called
var mockService = $injector.get( 'ParseService' );
mockService.registerBook = jasmine.createSpy("registerBook");
scope.registerNewBook(book);
//With this call we SPY the method registerBook of our mockservice
//we have to make sure that the register book have been called after the call of our Controller
expect(mockService.registerBook).toHaveBeenCalled();
});
it('Dummy test', function () {
expect(true).toBe(true);
});
});
현재 테스트는 불합격입니다.
Expected spy registerBook to have been called.
Error: Expected spy registerBook to have been called.
내가 뭘 잘못하고 있지?
제가 잘못하고 있었던 것은 각각 이전 컨트롤러에 모의 서비스를 주입하지 않은 것입니다.
describe('Controller: AddBookCtrl', function() {
var scope;
var ParseServiceMock;
var AddBookCtrl;
// load the controller's module
beforeEach(module('BookCrossingApp'));
// define the mock Parse service
beforeEach(function() {
ParseServiceMock = {
registerBook: function(book) {},
getBookRegistrationId: function() {}
};
});
// inject the required services and instantiate the controller
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
AddBookCtrl = $controller('AddBookCtrl', {
$scope: scope,
DataService: ParseServiceMock
});
}));
it('should call registerBook Parse Service method', function () {
var book = {title: "fooTitle"}
spyOn(ParseServiceMock, 'registerBook').andCallThrough();
//spyOn(ParseServiceMock, 'getBookRegistrationId').andCallThrough();
scope.registerNewBook(book);
expect(ParseServiceMock.registerBook).toHaveBeenCalled();
//expect(ParseServiceMock.getBookRegistrationId).toHaveBeenCalled();
});
});
서비스를 주입한 후 다음과 같이 spyOn.and.returnValue()를 사용할 수 있습니다.
beforeEach(angular.mock.module('yourModule'));
beforeEach(angular.mock.inject(function($rootScope, $controller, ParseService) {
mock = {
$scope: $rootScope.$new(),
ParseService: ParseService
};
$controller('AddBookCtrl', mock);
}));
it('should call Parse Service method', function () {
spyOn(mock.ParseService, "registerBook").and.returnValue({id: 3});
mock.$scope.registerNewBook();
expect(mock.ParseService.registerBook).toHaveBeenCalled();
});
하비토의 답변에 이어 4년 후.Jasmine은 2.0에서 구문을 변경하여 스파이에 대한 실제 메서드를 호출합니다.
변경:
spyOn(ParseServiceMock, 'registerBook').andCallThrough();
대상:
spyOn(ParseServiceMock, 'registerBook').and.callThrough();
프로젝트에 angular-mocks.js를 포함하여 다음 링크를 주의 깊게 읽어보십시오.
언급URL : https://stackoverflow.com/questions/15854043/mock-a-service-in-order-to-test-a-controller
반응형
'programing' 카테고리의 다른 글
iframe 내부에서 iframe을 닫는 방법은? (0) | 2023.02.24 |
---|---|
새로 고침 후 React-Redux 상태가 손실됨 (0) | 2023.02.24 |
React on Drop이 실행되지 않습니다. (0) | 2023.02.24 |
AngularJS에서 입력 트림을 비활성화하는 방법은 무엇입니까? (0) | 2023.02.24 |
ng-show/hide 대체 방법 또는 DOM의 관련 섹션만 로드하는 방법 (0) | 2023.02.24 |