无法注入模块/服务进行单元测试

问题描述:

我是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)... 
}); 

服务。

+0

谢谢你的真棒答案。我能够做到!唯一剩下的就是测试responseError函数,我将用该代码更新我的问题。你是否知道一种嘲笑响应错误函数动作的好方法,就像我嘲笑authInterceptor中的请求函数一样? – devdropper87

+0

这里是我的后续问题:http://*.com/questions/38985850/angular-js-karma-chai-mock-an-authorization-error – devdropper87

这意味着NG模块加载失败。 :)这种情况发生在引导应用程序和ng模块首先在三元素数组中:ng,['$ provide',function($ provide){...}]和我自己的应用程序模块。加载第一个时失败。

我看了一下控制台,并从中复制了此错误消息。没有其他错误。没有。

我希望你点击那个特定的链接,看看它没有给你任何具体的想法。不幸的是,我在耗尽其他资源之后添加了这个GitHub问题。我目前正在调试角码以获得更多。