我使用angular translate from here (http://pascalprecht.github.io/angular-translate/),它工作得很好,但它错误地破坏了我控制器单元测试:
Unexpected request: GET scripts/i18n/locale-en.json我不明白为什么?
我使用yeoman并使用karma进行测试。
app.js:
'use strict';
(function() {
angular.module('wbApp', ['authService', 'authUserService', 'checkUserDirective', 'ui.bootstrap', 'pascalprecht.translate'])
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl',
access: {
isFree: true
}
})
.when('/main', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
access: {
isFree: false
}
})
.otherwise({
redirectTo: '/'
});
});
})();configTranslate.js:
'use strict';
(function() {
angular.module('wbApp')
.config(['$translateProvider',
function($translateProvider) {
$translateProvider.useStaticFilesLoader({
prefix: 'scripts/i18n/locale-',
suffix: '.json'
});
$translateProvider.preferredLanguage('en');
}]);
})();karma.conf.js:
files = [
...
'app/bower_components/angular-translate/angular-translate.js',
'app/bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
...
];控制器测试:
'use strict';
describe('Controller: LoginCtrl', function() {
// load the controller's module
beforeEach(module('wbApp'));
var LoginCtrl, scope, location, httpMock, authUser;
// Initialize the controller and a mock scope
beforeEach(inject(function($controller, $rootScope, $location, $httpBackend, AuthUser) {
authUser = AuthUser;
location = $location;
httpMock = $httpBackend;
scope = $rootScope.$new();
LoginCtrl = $controller('LoginCtrl', {
$scope: scope
});
httpMock.when('GET', 'scripts/i18n/locale-en.json').passThrough();
}));
it(...);
...
});如果我将此代码添加到测试控制器中,则会产生相同的错误:
httpMock.when('GET', 'scripts/i18n/locale-en.json').respond(200);
httpMock.flush();或
httpMock.when('GET', 'scripts/i18n/locale-en.json').passThrough();
httpMock.flush();我发现这个帖子How do I test controllers with Angular Translate initialized in App Config?,但对我没有帮助:/
我在测试中广泛使用了$httpBackend,它工作得很好,但在这种情况下,它是无效的。如果我注释这行:
$translateProvider.preferredLanguage('en');显然是一个错误,如果我添加了运行时(在我的控制器中)
$translate.uses(local);我最终会出现同样的错误吗?
因此,我转向转换配置(configTranslate.js)或在运行时是相同的结果:
Unexpected request: GET scripts/i18n/locale-en.json下面是我测试的语法,或者在"beforeEach(inject(function(...});“
或者在测试中"it('...',function() {...});“
httpMock.expectGET('scripts/i18n/locale-en.json');
httpMock.when('GET', 'scripts/i18n/locale-en.json').passThrough();
httpMock.when('GET', 'scripts/i18n/locale-en.json').respond(data);在结尾处
httpMock.flush();我还尝试了$ apply
httpMock.expectGET('scripts/i18n/locale-fr.json');
scope.$apply(function(){
$translate.uses('fr');
});
httpMock.flush();什么都没发生,但这个错误还是让我抓狂。
如果你有任何建议
发布于 2014-11-29 01:39:12
这是一个已知问题,请遵循此处的文档:unit testing angular
The solution
不幸的是,这个问题是由角度平移的设计引起的。为了避免这些错误,我们所能做的就是在我们的测试套件中重写我们的模块配置,它根本不使用异步加载器。如果没有异步加载器,就没有XHR,因此不会出现错误。
那么我们如何在运行时为我们的测试套件覆盖我们的模块配置呢?在实例化一个angular模块时,我们总是可以应用一个内联函数,该函数作为配置函数来执行。此配置函数可用于覆盖模块配置,因为我们可以访问所有提供程序。
使用$provide提供程序,我们可以构建一个自定义加载器工厂,然后应该使用它来代替静态文件加载器。
beforeEach(module('myApp', function ($provide, $translateProvider) {
$provide.factory('customLoader', function () {
// loader logic goes here
});
$translateProvider.useLoader('customLoader');
}));请在上面提供的链接中阅读更多。
发布于 2015-04-06 23:19:20
我们采取了在单元测试中忽略转换加载器的方法,而不是被迫修改每个规范文件。
一种方法是将加载器配置分离到一个单独的文件中,然后在karma中排除它。
因此,例如,您可以创建文件app-i18n-loader.js (所有其他模块配置都在不同的文件中进行):
angular
.module('myApp')
.config(loaderConfig);
loaderConfig.$inject = ['$translateProvider', '$translatePartialLoaderProvider'];
function loaderConfig($translateProvider, $translatePartialLoaderProvider) {
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: 'assets/i18n/{part}/{lang}.json'
});
$translatePartialLoaderProvider.addPart('myApp');
}并在您的karma.conf.js中排除该文件:
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
//...
'bower_components/angular-translate/angular-translate.js',
'bower_components/angular-translate-loader-partial/angular-translate-loader-partial.js',
'app/**/*.mdl.js',
'app/**/*.js'
],
exclude: [
'app/app-i18n-loader.js'
],(注:答案已编辑为不需要哼唱/吞咽的解决方案)。
发布于 2015-12-16 03:47:54
我想要一个解决方案,
<代码>G29
这就是我最终得到的结论:
// you need to load the 3rd party module first
beforeEach(module('pascalprecht.translate'));
// overwrite useStaticFilesLoader to get rid of request to translation file
beforeEach(module(function ($translateProvider) {
$translateProvider.useStaticFilesLoader = function () {
};
}));假设您的单元测试不需要实际的翻译,这将非常有效。只需将beforeEach放在全局级别上,最好放在测试文件夹内它自己的文件中。然后,它将在所有其他测试之前执行。
https://stackoverflow.com/questions/18876290
复制相似问题