1

I'm trying to set up tests, where we are using Angular 1.5, TSify, and Karma. I'm very, close, but I'm running into an issue that I haven't quite got right:

I'm following the setup described here: https://github.com/cmlenz/tsify-test (this example doesn't include angular)

I get an error from angular-mocks: "Cannot set property 'mock' of undefined"

That has to be either a timing thing or a scope thing -- either angular-mocks is loading too soon, or browserify is wrapping up the scope of the angular variable, and mocks can't see it. No idea.

Here are the pertinent parts of my karma.conf.js file:

    frameworks: ['browserify', 'jasmine'],

    files: [
        'https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js',
        './node_modules/angular-mocks/angular-mocks.js',
        './modules/**/*.spec.ts'
    ],

    exclude: [],

    preprocessors: {
        '**/*.ts': 'browserify'
    },

    browserify: {
        debug: true,
        plugin: [
            ['tsify']
        ]
    },

This must have something to do with the way I'm loading mocks -- it's not used by my angular app, just the tests, so that must have something to do with it.

Any hints?

JMarsch
  • 21,484
  • 15
  • 77
  • 125
  • 1
    Your `files` array should include **all** the files required to test. Where is `angular.js` as well as your application files? – Phil Sep 13 '16 at 00:55
  • 1
    From your configuration, it's apparent that `angular-mocks` was installed with NPM. If `angular` was also installed with NPM and is being included in the bundle via a `require` in a `.ts` file, that is likely the problem, as `angular-mocks` needs to load after `angular`. – cartant Sep 13 '16 at 12:05
  • @Phil Browserify is concatenating all of the files (including vendor files) into a single bundle. In the example that I am working from, they just registered the **/*.ts glob in the pre-processor section. If that's not right, I can change it. What should it be? (I'm assuming that I should not have to specifically point to each vendor file, since browserify is packing those into the bundle). – JMarsch Sep 13 '16 at 14:23
  • @cartant you are correct -- we are using NPM for the vendor scripts, and in our typscript, we are importing the modules and using the CommonJS compiler flag. We then use browserify with the tsify plug-in to compile our typscript, and to bundle the imported vendor scripts for the browser. I think that where we are breaking down is that I don't import angular-mocks anywhere in the main application. Is there a way to import angular-mocks for my testing, but not import it in prod builds? – JMarsch Sep 13 '16 at 14:26
  • I'll add an answer - primarily because there's insufficient space in a comment - but, yes, there'd be numerous ways to do it. – cartant Sep 13 '16 at 21:19

1 Answers1

1

angular-mocks needs to be loaded after angular and with your current Karma configuarion, that's not happening - angular is not being loaded until it's required in one of the .ts files upon which one of your .spec.ts files is dependent.

One solution would be to add an additional file that requires both angular and angular-mocks and to ensure that file precedes the .spec.ts files in Karma's files configuration.

For example, a file named require-angular-mocks.js could be created:

require('angular');
require('angular-mocks');

And could be added to the Karma configuration (replacing the angular-mocks under node_modules):

files: [
    'https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js',
    './require-angular-mocks.js',
    './modules/**/*.spec.ts'
],

preprocessors: {
    '**/*.js': 'browserify',
    '**/*.ts': 'browserify'
},

That should ensure that angular and angular-mocks are loaded in the correct order and are loaded before your specs. Note that if it's a .js file, you'll need another entry in Karma's preprocessors configuration.

cartant
  • 57,105
  • 17
  • 163
  • 197
  • Got pulled off-task, and just came by to try this. It worked! That was great! Thank you for your help. I would like to understand more about how the karma pipeline is working. Do you know of a write-up for that? – JMarsch Sep 28 '16 at 18:19
  • Unfortunately, no, I don't know of any useful write ups for Karma. I guess my understanding has gradually accreted by reading through the [configuration documenation](http://karma-runner.github.io/1.0/config/configuration-file.html) to solve at-hand problems. The [`files`](http://karma-runner.github.io/1.0/config/files.html) setting is the crux of it. Karma uses that to build the HTML file that it serves up. The Browserify thing must work by reducing the `.js` entries in `files` to a single bundle that's included as a ` – cartant Sep 29 '16 at 08:37
  • I guess I'll have to build the same way. I ran into one thing that surprised me: We are using typescript, and I had originally thought that the .ts files were to be fed into the preprocessor, and to put the .js files in the files block. Instead, I found that I needed to specify the .ts files in both the preprocessor and the files block, so I'm guessing that the pipeline goes from files to preprocessor to karma's server -- or at least that the creation of the source stream from files occurs before preprocessing. – JMarsch Sep 29 '16 at 14:26