无法注入模块/服务进行单元测试
问题描述:
我是TDD的新手,试图连接测试,并且一直困扰它数小时。我不断收到以下错误:无法注入模块/服务进行单元测试
[$injector:modulerr] Failed to instantiate module AuthInterceptor due to:
Error: [$injector:nomod] Module 'AuthInterceptor' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.5.8/$injector/nomod?p0=AuthInterceptor
at client/test/index.js:8237:13
at client/test/index.js:10251:18
at ensure (client/test/index.js:10175:39)
at module (client/test/index.js:10249:15)
at client/test/index.js:12786:23
at forEach (client/test/index.js:8490:21)
at loadModules (client/test/index.js:12770:6)
这里是我的测试:
import angular from 'angular';
import serviceModule from './auth.interceptor'
describe('wire.common.services',() => {
describe('AuthService',() => {
let AuthService;
beforeEach(angular.mock.module(serviceModule.name));
beforeEach(angular.mock.module(($provide) => {
$provide.factory('$q',() => ({}));
$provide.factory('$log',() => ({}));
}));
beforeEach(angular.mock.inject((_AuthService_) => {
AuthService = _AuthService_;
}));
it('should be a dummy test',() => {
expect(2).toEqual(2);
});
});
});
实际的代码我测试:
export default function AuthInterceptor($q, $injector, $log) {
'ngInject';
return {
request(config) {
let AuthService = $injector.get('AuthService');
if (!config.bypassAuthorizationHeader) {
if (AuthService.jwtToken) {
config.headers.Authorization = `Bearer ${AuthService.jwtToken}`;
} else {
$log.warn('Missing JWT', config);
}
}
return config || $q.when(config);
},
responseError(rejection) {
let AuthService = $injector.get('AuthService');
if (rejection.status === 401) {
AuthService.backToDAS();
}
return $q.reject(rejection);
}
};
}
我不明白为什么我得到这个错误 - 我提供了服务的所有依赖关系,并遵循angular文档中概述的内容。任何帮助表示赞赏!
更新,这是我去的代码:
import angular from 'angular';
import AuthInterceptor from './auth.interceptor'
describe('Auth interceptor test',() => {
describe('AuthInterceptor test',() => {
let $httpBackend, $http, authInterceptor = AuthInterceptor();
beforeEach(angular.mock.module(($httpProvider, $provide) => {
$httpProvider.interceptors.push(AuthInterceptor);
$provide.factory('AuthService',() => ({
jwtToken: "hello",
backtoDAS: angular.noop
}));
}));
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$http = $injector.get('$http');
}))
it('should have a request function',() => {
let config = {};
expect(authInterceptor.request).to.be.defined;
expect(authInterceptor.request).to.be.a('function');
})
it('the request function should set authorization headers', (done) => {
$httpBackend.when('GET', 'http://jsonplaceholder.typicode.com/todos')
.respond([{
id: 1,
title: 'Fake title',
userId: 1
}]);
$http.get('http://jsonplaceholder.typicode.com/todos').then(function(transformedResult) {
expect(transformedResult.config.headers.Authorization).to.be.defined;
expect(transformedResult.config.headers.Authorization).to.contain('Bearer')
done();
})
$httpBackend.flush();
});
it('should have a responseError function',() => {
expect(authInterceptor.responseError).to.be.defined;
expect(authInterceptor.responseError).to.be.a('function');
//TODO: test return value
// see that AuthService.backToDAS()
})
it('the error function should call backtoDAS', (done) => {
//the URL should be one that gives me a 401
$httpBackend.when('GET', 'https://wwws.mint.com/overview.event')
.respond([{
id: 1,
title: 'Fake title',
userId: 1
}]);
$http.get('https://wwws.mint.com/overview.event').then(function(transformedResult) {
console.log(transformedResult);
done();
}, function(error){
console.log(error);
done();
})
});
})
});
答
这意味着AuthInterceptor
角模块没有定义(顺便说一句,依靠name
是不安全的)。
AuthInterceptor
不是一个模块,而是一个注射功能。它可以在功能性的方式来测试作为$http
拦截:
beforeEach(angular.mock.module(($httpProvider) => {
$httpProvider.interceptors.push(AuthInterceptor);
});
...
it('...',() => {
$httpBackend.when(...).respond(...);
$http.get(...).then((interceptedResult) => {
expect(interceptedResult)...
});
$rootScope.$digest();
});
,或者直接:产生副作用(AuthService
,$log
)应该被存根
it('...',() => {
let interceptor = $injector.invoke(AuthInterceptor);
expect(interceptor).toEqual({
request: jasmine.any(Function),
requestError: jasmine.any(Function)
});
var config = { headers: {} };
interceptor.request(config);
expect(config)...
});
服务。
答
这意味着NG模块加载失败。 :)这种情况发生在引导应用程序和ng模块首先在三元素数组中:ng,['$ provide',function($ provide){...}]和我自己的应用程序模块。加载第一个时失败。
我看了一下控制台,并从中复制了此错误消息。没有其他错误。没有。
我希望你点击那个特定的链接,看看它没有给你任何具体的想法。不幸的是,我在耗尽其他资源之后添加了这个GitHub问题。我目前正在调试角码以获得更多。
谢谢你的真棒答案。我能够做到!唯一剩下的就是测试responseError函数,我将用该代码更新我的问题。你是否知道一种嘲笑响应错误函数动作的好方法,就像我嘲笑authInterceptor中的请求函数一样? – devdropper87
这里是我的后续问题:http://stackoverflow.com/questions/38985850/angular-js-karma-chai-mock-an-authorization-error – devdropper87