Vue-loader: vue loader module injection not working

Created on 15 Oct 2016  路  7Comments  路  Source: vuejs/vue-loader

Description:
I'm trying to mock my dependencies with inject-loader.
Here's my dependency:

export const name = "Awesome";
export const version = "1.0.0";

Here's the component:

<template>
  <header v-once class="header">
    <router-link to="/" class="brand">
      <span class="brand-name">{{ name }}</span>
      <span class="brand-version">{{ version }}</span>
    </router-link>
  </header>
</template>

<script>
  import { name, version } from '../../../services/brand';
  export default {
    name: 'Header',
    data() {
      return {
        name,
        version
      };
    }
  };
</script>

<style lang="sass" rel="stylesheet/scss" scoped>
...
</style>

spec file:

it('should render brand correctly', () => {
    const headerInjector = require('!!vue?inject!./Header.vue');
    const MockedHeader = headerInjector({
      '../../../services/brand': {
        name: "Test",
        version: "1.2.3"
      }
    });
    const vm = new Vue({
      template: '<div><header></header></div>',
      components: {
        header: MockedHeader
      }
    }).$mount();
    expect(vm.$el.querySelector('.brand-name').textContent).toBe('Test');
    expect(vm.$el.querySelector('.brand-version').textContent).toBe('1.2.3');
  });

When running my test with karma, I get the following error:

TypeError: undefined is not a constructor (evaluating 'vue_exports(injections)')

Karma config:

const configuration = {
    basePath: '../',
    singleRun: true,
    autoWatch: false,
    logLevel: 'INFO',
    junitReporter: {
      outputDir: 'test-reports'
    },
    browsers: [
      'PhantomJS'
    ],
    frameworks: [
      'jasmine'
    ],
    files: [
      'node_modules/es6-shim/es6-shim.js',
      conf.path.src('app.spec.js')
    ],
    preprocessors: {
      [conf.path.src('app.spec.js')]: [
        'webpack'
      ]
    },
    reporters: ['progress', 'coverage'],
    coverageReporter: {
      type: 'html',
      dir: 'coverage/'
    },
    webpack: require('./webpack-test.conf'),
    webpackMiddleware: {
      noInfo: true
    },
    plugins: [
      require('karma-jasmine'),
      require('karma-junit-reporter'),
      require('karma-coverage'),
      require('karma-phantomjs-launcher'),
      require('karma-phantomjs-shim'),
      require('karma-webpack')
    ]
  };

webpack config in use:

module.exports = {
  module: {
    preLoaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint'
      }
    ],
    loaders: [
      {
        test: /.json$/,
        loader: 'json'
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel'
      },
      {
        test: /.vue$/,
        loader: 'vue'
      }
    ]
  },
  plugins: [],
  debug: true,
  devtool: 'source-map'
};

Environment:
OS win10x64
vue-loader 9.3.2
webpack 2.1.0-beta.20
babel-core 6.13.0
babel-loader 6.2.0
babel-preset-es2015 6.2.0
vue 2.0.0-rc.6

Most helpful comment

Having the same issue on inject-loader v2.0.1.

TypeError: Object is not a constructor (evaluating '__vue_exports__(injections)')

I only get this issue if I use the mock twice:

const Mock = require('!!vue?inject!src/foo.vue')
console.log(Mock({}))
console.log(Mock({}))

The second call will throw the error.

All 7 comments

Was experiencing the same thing, seems to be an issue with version 3+ of inject loader. Perhaps the docs needs to be updated.

force the version in your package.json

    "inject-loader": "^2.0.1",

Yea seems to be the problem :)

Having the same issue on inject-loader v2.0.1.

TypeError: Object is not a constructor (evaluating '__vue_exports__(injections)')

I only get this issue if I use the mock twice:

const Mock = require('!!vue?inject!src/foo.vue')
console.log(Mock({}))
console.log(Mock({}))

The second call will throw the error.

@sagalbot Did you ever figure out the solution to this? It's exactly the issue I'm having right now.

@sagalbot, @adiakritos the issue with using the injector twice was filed in issue #434.

Hi guys,

This is still a problem with [email protected]

This is my code:

const LoginInjector = require('!!vue-loader?inject-loader!../../../src/views/Login.vue')
  const LoginMock = LoginInjector({
    '../utils/constants': {
      msg: 'Hello from a mocked service!'
    },
    '../components/FormContainer.vue': {
      test: 'hello'
    }
  })
  it ('Check onSubmit with valid email and password', (done) => {
    const vm = new Vue({
      template: '<div><test></test></div>',
      components: {
        'test': LoginMock
      }
    }).$mount()
    done()
  })

karma.conf.js

var webpackConfig = require('../../build/webpack.test.config')

module.exports = function (config) {
  config.set({
    browsers: ['PhantomJS'],
    frameworks: ['mocha', 'sinon-chai', 'es6-shim'],
    reporters: ['spec', 'coverage'],
    files: ['./index.js'],
    preprocessors: {
      './index.js': ['webpack']
    },
    webpack: webpackConfig,
    webpackMiddleware: {
      noInfo: true
    },
    colors: true,
    coverageReporter: {
      dir: './coverage',
      reporters: [
        { type: 'lcov', subdir: '.' },
        { type: 'text-summary' }
      ]
    }
  })
}

Please let me know how did you guys resolve this issue?

I came up an idea to solve this problem, if you meet the issue same as me.

My issue is:

I have a vue component, the component include a API.js file as a library. I need to mockup the library.

what I did, I create another API.js in test folder, and change webpack configuration of "resolve" part for test.

like this:

resolve: {
alias: {
'API.js': '../../test/unit/API.js'
}
}

in this way we don't need inject-loader any more.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yozman picture yozman  路  4Comments

amorphine picture amorphine  路  3Comments

flashios09 picture flashios09  路  3Comments

Makio64 picture Makio64  路  4Comments

NextSeason picture NextSeason  路  3Comments