Angular error running Karma tests: HTML5 mode requires a <base> tag

被刻印的时光 ゝ 提交于 2019-12-17 16:30:24

问题


I have a single-page Angular app with a Rails backend. I am using a tag in my index.html file, but when I run my front-end unit tests using Karma, I get this:

$location in HTML5 mode requires a <base> tag to be present

I am doing this in my main .js file:

angular.module('my.module').config( function($locationProvider, $routeProvider) {
  $locationProvider.html5Mode( true );
}

So, is there any way I can inject a <base> element in the page that karma actually renders? Or else, tell Angular/Karma to ignore this error when running unit tests?

Update

This Google Groups thread and this GitHub issue both describe this problem but in both cases the solution is to simply bump up the version of Angular. I've done that and I can even see the line in angular-mocks.js where the default baseHref gets set...

Here is the spec in question:

describe 'amnResource', ->
  $compile = null
  $rootScope = null

  beforeEach ->
    module 'ngMock'
    module 'amn'
    module 'directive.template.cache'

    inject([ '$compile', '$rootScope', ($c, $r) ->
      $compile = $c
      $rootScope = $r
    ])

  it 'compiles to an article', ->
    console.log $rootScope
    console.log $rootScope.foo
    $rootScope.foo =
      title: 'Foo'
      excerpt: 'foo bar qux'

    element = $compile('<amn-resource resource="foo"></amn-resource>')($rootScope)
    console.log element.html()
    console.log $rootScope.foo
    expect( element.html() ).toMatch /Foo/

Karma output:

Running "karma:unit" (karma) task
INFO [karma]: Karma v0.12.28 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 39.0.2171 (Mac OS X 10.9.5)]: Connected on socket hOvsC6ji15heHZmiHxJt with id 45528987
ERROR: 'Error: [$location:nobase] $location in HTML5 mode requires a <base> tag to be present!
http://errors.angularjs.org/1.3.5/$location/nobase
    at http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:63:12
    at $LocationProvider.$get (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:11187:15)
    at Object.invoke (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4138:17)
    at $LocationProvider.origProvider.$get (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4024:43)
    at Object.invoke (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4138:17)
    at http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:3956:37
    at getService (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4097:39)
    at Object.invoke (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4129:13)
    at http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:3956:37
    at getService (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4097:39)'
ERROR: 'Error: [$location:nobase] $location in HTML5 mode requires a <base> tag to be present!
http://errors.angularjs.org/1.3.5/$location/nobase
    at http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:63:12
    at $LocationProvider.$get (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:11187:15)
    at Object.invoke (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4138:17)
    at $LocationProvider.origProvider.$get (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4024:43)
    at Object.invoke (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4138:17)
    at http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:3956:37
    at getService (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4097:39)
    at Object.invoke (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4129:13)
    at http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:3956:37
    at getService (http://localhost:9876/base/vendor/assets/javascripts/angular/angular.js?3a16995fbea0062d6334adb9277e9776ca069fa1:4097:39)'
Chrome 39.0.2171 (Mac OS X 10.9.5) Midway: Resource performs a GET request FAILED
    Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
LOG: Scope{$id: 2, $$childTail: null, $$childHead: null, $$prevSibling: null, $$nextSibling: null, $$watchers: null, $parent: null, $$phase: null, $root: Scope{$id: 2, $$childTail: null, $$childHead: null, $$prevSibling: null, $$nextSibling: null, $$watchers: null, $parent: null, $$phase: null, $root: Scope{$id: ..., $$childTail: ..., $$childHead: ..., $$prevSibling: ..., $$nextSibling: ..., $$watchers: ..., $parent: ..., $$phase: ..., $root: ..., $$destroyed: ..., $$listeners: ..., $$listenerCount: ..., $$isolateBindings: ..., $$asyncQueue: ..., $$postDigestQueue: ..., $$applyAsyncQueue: ...}, $$destroyed: false, $$listeners: Object{}, $$listenerCount: Object{}, $$isolateBindings: null, $$asyncQueue: [], $$postDigestQueue: [], $$applyAsyncQueue: []}, $$destroyed: false, $$listeners: Object{}, $$listenerCount: Object{}, $$isolateBindings: null, $$asyncQueue: [], $$postDigestQueue: [], $$applyAsyncQueue: []}
LOG: undefined
LOG: ''
LOG: Object{title: 'Foo', excerpt: 'foo bar qux'}
Chrome 39.0.2171 (Mac OS X 10.9.5) amnResource compiles to an article FAILED
    Expected '' to match /Foo/.
    Error: Expected '' to match /Foo/.
        at Object.<anonymous> (/Users/acobster/Dropbox/amn/amn-0.5/spec/javascripts/unit/directives/resource_spec.js:27:35)
Chrome 39.0.2171 (Mac OS X 10.9.5): Executed 3 of 3 (2 FAILED) (5.078 secs / 5.074 secs)

回答1:


You can disable the base tag check by doing the following:

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});



回答2:


You can specify your base tag in your index.html <head> like that:

<head>
  <base href="/">
  ...
</head>

Source: from angularjs documentation




回答3:


If you can't or do not want to set requireBase to false, the solution - as others pointed out - is to add <base href="/"> in the header of your primary HTML file. To do this, you will need to specify custom HTML files for Karma, which you can then edit.

First find and copy node_modules/karma/static/context.html and node_modules/karma/static/debug.html to your unit test folder, and amend the headers of both.

Then in your karma.conf.js add the following two lines:

customContextFile: 'test/unit/context.html',
customDebugFile:   'test/unit/debug.html',

Of course your path may vary.



来源:https://stackoverflow.com/questions/27307914/angular-error-running-karma-tests-html5-mode-requires-a-base-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!