【问题标题】:inject gives throws Error: [ng:areq] Argument 'fn' is not a function, got string注入抛出错误:[ng:areq] 参数 'fn' 不是函数,得到字符串
【发布时间】:2015-05-10 18:40:55
【问题描述】:

我是 AngularJS 的新手,我尝试以测试驱动的方式开发 AngularJS 应用程序和咖啡脚本,但无法注入工作。 为了创建项目,我使用 yeoman 进行设置:

yo angular --coffee someapp

然后我创建了测试和提供者使用

yo angular:provider testProvider

提供者如下所示:

angular.module 'SomeApp'
  .provider 'someApi', ->

    # Private variables
    salutation = 'Hello'

    # Private constructor
    class Greeter
      greet: () ->
        salutation

    # Public API for configuration
    @set_salutation = (s) ->
      salutation = s 

    # Method for instantiating
    @$get = ->
      new Greeter()

    return

这是我要测试的提供者的单元测试:

 someApi = {'test': 'gets assigned'}

  # load the service's module
  beforeEach () ->
    console.log('service module')
    module 'SomeApp', (someApiProvider) ->
        someApiProvider.set_salutation("Hey Guys")

  beforeEach () ->
    console.log('inject')
    inject( 
      ('_someApi_') ->
    )
    console.log('after inject')

  it 'should do something', ->
    expect(!!soeaidApi).toBe true

我尝试了不同版本的注入调用,例如:

inject()

inject(
  (_someApi_) ->
      someApi = _someApi_
) 

inject((_httpBackend_) -> )

还有更多,但我在日志中看不到“注入后”,并且业力的输出保持不变:

PhantomJS 1.9.8 (Linux) Service: someApi should do something FAILED
    Error: [ng:areq] Argument 'fn' is not a function, got string
    http://errors.angularjs.org/1.3.14/ng/areq?p0=fn&p1=not%20a%20function%2C%20got%20string
        at assertArg ($PROJ_ROOT/angular_app/bower_components/angular/angular.js:1580)
        at assertArgFn ($PROJ_ROOT/angular_app/bower_components/angular/angular.js:1591)
        at annotate ($PROJ_ROOT/angular_app/bower_components/angular/angular.js:3474)
        at $PROJ_ROOT/angular_app/bower_components/angular-mocks/angular-mocks.js:2147
        at invoke ($PROJ_ROOT/angular_app/bower_components/angular/angular.js:4163)
        at $PROJ_ROOT/angular_app/bower_components/angular/angular.js:4007
        at forEach ($PROJ_ROOT/angular_app/bower_components/angular/angular.js:323)
        at createInjector ($PROJ_ROOT/angular_app/bower_components/angular/angular.js:4007)
        at workFn ($PROJ_ROOT/angular_app/bower_components/angular-mocks/angular-mocks.js:2353)

但如果我注释掉注入行,我会看到“注入后”日志(显然)。 我错过了什么,我是否以错误的方式调用注入,如果是,如何正确执行? 'fn' 参数的错误日志是什么意思?

【问题讨论】:

  • 在什么模块中定义了“someApi”。您需要定义一个像 angular.module("some_module") 这样的模块。然后你需要定义一些Api。否则仅仅将它定义为一个对象是行不通的。像 angular.module("some_module").factory("someApi", [function() {return ...}]) 这样的事情需要做。然后在单元测试中你需要做 beforeEach(module('some_module')); beforeEach(inject(function(someApi){}));
  • 抱歉含糊不清,我更新了我的问题以包含被测单元

标签: angularjs unit-testing coffeescript karma-jasmine


【解决方案1】:

我终于弄清楚了如何正确配置提供程序并注入所有依赖项。在尝试测试您的提供者时,这也是所有苦苦挣扎的人的 sn-p。

这里是被测单元:

class APIObject
  constructor: (@api_url) ->

  get_something: () ->
    console.log('get_something on ' + @api_url)
    return @$http({
      'method': 'GET'
      'url': @api_url + '/something/'
    })  

  with_http: ($http) ->
    @$http = $http
    return this


someApiFunc = () ->
  current_obj = new APIObject('not configured')

  @set_api_url = (api_url) ->
    console.log('set ' + api_url)
    current_obj = new APIObject(api_url)
    return

  @$get = ($http) ->
    # inject external dependencies here (like the $http service)
    return current_obj.with_http($http)

  return


angular.module('SomeApp').provider 'someApi', someApiFunc

这是(还不是很复杂的)测试:

describe 'Test', ->

  beforeEach () ->
    # get mock of someApp and configure it here
    module('someApp',
           (someApiProvider) ->
             # inject the parts you need to configure here.
             # we are still in the configuration phase here
             # and someApi isnt yet created, but someApiProvider 
             # is here yet to allow us to configure the creation
             someApiProvider.set_api_url('TEST_URL')
             return
    )
    return

  service_available_to_app = {}
  $httpBackend = {}
  beforeEach () ->
    inject (someApi, _$httpBackend_) ->
        # just make the injections available to the outside world.
        # here someApi is available and configured according to
        # someApiProvider
        service_available_to_app = someApi
        $httpBackend = _$httpBackend_

  it 'should getSomething and use configured api_url', () ->
    $httpBackend.expectGET('TEST_URL/something/').respond(200, {'id': '1'})
    sessions = service_available_to_app.get_something()
    $httpBackend.flush()
    expect(sessions).not.toBe(undefined)

  afterEach () ->
    $httpBackend.verifyNoOutstandingExpectation()
    $httpBackend.verifyNoOutstandingRequest()

  return

【讨论】:

    猜你喜欢
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多