我使用的是ES6,AngularJS,Karma / Jasmine和angular-translate。似乎无法让我的单元测试通过。在单元测试方面,不太确定如何使用第三方模块,如angular-translate。我得到的代码和错误如下。 $ translateProvider未加载。
import CatalogueModule from './catalogue.module'
import CatalogueService from './catalogue.service'
let service,
_$translateProvider;
describe('CatalogueService', () => {
beforeEach(angular.mock.module(CatalogueModule));
beforeEach(() => {
angular.mock.module({
$translateProvider: jasmine.createSpyObj('$translateProvider',
['translations', 'preferredLanguage']
),
$translate: jasmine.createSpyObj('$translate',
['use']
)
});
})
beforeEach(inject(($translateProvider) => {
_$translateProvider = $translateProvider;
_$translateProvider.translations('en', {});
_$translateProvider.preferredLanguage('en');
// service = new CatalogueService();
}));
it('should set the config object after initialization', inject(($translateProvider, CatalogueService) => {
// $translateProvider.use.and.returnValue();
// expect(service.config.headers).to.equal(null);
}));
});
这是错误:
✖ "before each" hook: WorkFn for "should set the config object after initialization"
Chrome 59.0.3071 (Mac OS X 10.12.3)
Error: [$injector:unpr] Unknown provider: $translateProviderProvider <- $translateProvider
更新 - 添加catalogue.service.js
class CatalogueService {
constructor($http, $q, $translate) {
'ngInject';
this._$http = $http;
this._$q = $q;
this._$translate = $translate;
this.config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': '******',
'P3-APP-ID': '*****',
'P3-Date': '*****'
}
};
this.catalogue = this.getCatalogue();
}
getCatalogue() {
const lang = this._$translate.use();
const url = `https://somedomain.com/catalog?language_code=${lang}`;
const deferred = this._$q.defer();
this._$http
.get(url, this.config)
.then(
(res) => deferred.resolve(res.data.characters),
(err) => deferred.reject(err)
);
return deferred.promise;
};
getCharacterByCharId(charId) {
return this.catalogue
.then((res) => {
return res.find((character) => {
return character.link_name === charId;
});
});
};
}
export default CatalogueService;
答案 0 :(得分:2)
没有
beforeEach(angular.mock.module(...))
在测试中。这意味着在当前测试中仅加载ng
和ngMock
模块,并且没有$translateProvider
服务。
最好通过用DI实例化它们来测试角度单位,而不是直接测试。这允许测试服务注释和类内部。
非常希望保持单元测试被隔离并消除每个单元,但是测试中的单元,尤其是第三方库。如果测试单位需要$translateProvider
,则最好将其替换为模拟或存根:
beforeEach(angular.mock.module('moduleThatContainsCatalogueService');
beforeEach(() => {
angular.mock.module({
$translateProvider: jasmine.createSpyObj('$translateProvider',
['translations', 'preferredLanguage', 'use']
)
});
})
it('...', inject(($translateProvider, catalogueService) => {
$translateProvider.use.and.returnValue(...);
...
}));
答案 1 :(得分:0)
我之前使用$translateProvider
的自定义加载程序完成了此操作。这个例子是打字稿,但是这样的东西对你也有用:
angular.mock.module(($provide: angular.auto.IProvideService, translateProvider: angular.translate.ITranslateProvider) => {
$provide.factory('customLoader', ($q: angular.IQService) =>
() => {
const deferred = $q.defer();
deferred.resolve({});
return deferred.promise;
});
$translateProvider.useLoader('customLoader');
});