Tôi có cách myServicesử dụng myOtherServiceđó, thực hiện cuộc gọi từ xa, trả lại lời hứa:
angular.module('app.myService', ['app.myOtherService'])
.factory('myService', [
myOtherService,
function(myOtherService) {
function makeRemoteCall() {
return myOtherService.makeRemoteCallReturningPromise();
}
return {
makeRemoteCall: makeRemoteCall
};
}
])
Để thực hiện một bài kiểm tra đơn vị cho myServicetôi cần phải chế giễu myOtherService, sao cho makeRemoteCallReturningPromisephương thức của nó trả về một lời hứa. Đây là cách tôi làm điều đó:
describe('Testing remote call returning promise', function() {
var myService;
var myOtherServiceMock = {};
beforeEach(module('app.myService'));
// I have to inject mock when calling module(),
// and module() should come before any inject()
beforeEach(module(function ($provide) {
$provide.value('myOtherService', myOtherServiceMock);
}));
// However, in order to properly construct my mock
// I need $q, which can give me a promise
beforeEach(inject(function(_myService_, $q){
myService = _myService_;
myOtherServiceMock = {
makeRemoteCallReturningPromise: function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
}
};
}
// Here the value of myOtherServiceMock is not
// updated, and it is still {}
it('can do remote call', inject(function() {
myService.makeRemoteCall() // Error: makeRemoteCall() is not defined on {}
.then(function() {
console.log('Success');
});
}));
Như bạn có thể thấy ở trên, định nghĩa về giả của tôi phụ thuộc vào $q, mà tôi phải tải bằng cách sử dụng inject(). Hơn nữa, việc tiêm thuốc giả sẽ xảy ra module(), điều này sẽ đến trước inject(). Tuy nhiên, giá trị cho giả không được cập nhật khi tôi thay đổi.
Cách thích hợp để làm điều này là gì?
myService.makeRemoteCall()? Nếu vậy, vấn đề làmyServicekhông cómakeRemoteCall, không có gì để làm với sự chế giễu của bạnmyOtherService.