4

I've used ng new my-app --minimal to scaffold an Angular 5 CLI app to play around with. After doing so for a bit, I found that I did want a spec file for something. So what I did was:

  1. Create a file /src/app/my-thing.ts with a class
  2. Create a file /src/app/my-thing.spec.ts with content describe('MyThing', () => { ... }

But obviously describe(...) cannot be found, because --minimal skips setting up tests, so there's nothing there to support it.

How do I properly add a tests setup that'll work nicely with ng test?

Jeroen
  • 60,696
  • 40
  • 206
  • 339
  • You'll need jasmine for sure – BradleyDotNET Jun 05 '18 at 19:23
  • @BradleyDotNET Thx for the reply. My first attempt was just `npm i jasmine` and go from there, but it didn't end well so after a bit I decided to do a more 'brute force' appraoch. I've shared it as an answer, but still hope someone can teach me a smarter way/trick. – Jeroen Jun 05 '18 at 19:28

1 Answers1

6

I'd prefer to learn if there's a CLI-based solution for this, but for now I've just pushed on and used some git, diff, and cli magic to see what was needed to get up and running. Here's the dumb solution:

  1. Update .angular-cli.json removing:

    "class": {
      "spec": false
    }
    
  2. Update .angular-cli.json setting "spec": false to true everywhere inside "component"

  3. Add these to package.json:

    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    

    and run npm install to get those packages installed.

  4. Add this (or similar) in a new file karma.conf.js in the project root:

    module.exports = function (config) {
      config.set({
        basePath: '',
        frameworks: ['jasmine', '@angular/cli'],
        plugins: [
          require('karma-jasmine'),
          require('karma-chrome-launcher'),
          require('karma-jasmine-html-reporter'),
          require('karma-coverage-istanbul-reporter'),
          require('@angular/cli/plugins/karma')
        ],
        client:{
          clearContext: false // leave Jasmine Spec Runner output visible in browser
        },
        coverageIstanbulReporter: {
          reports: [ 'html', 'lcovonly' ],
          fixWebpackSourcePaths: true
        },
        angularCli: {
          environment: 'dev'
        },
        reporters: ['progress', 'kjhtml'],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ['Chrome'],
        singleRun: false
      });
    };
    
  5. Add this to a new file src/test.ts:

    import 'zone.js/dist/zone-testing';
    import { getTestBed } from '@angular/core/testing';
    import {
      BrowserDynamicTestingModule,
      platformBrowserDynamicTesting
    } from '@angular/platform-browser-dynamic/testing';
    
    declare const require: any;
    
    // First, initialize the Angular testing environment.
    getTestBed().initTestEnvironment(
      BrowserDynamicTestingModule,
      platformBrowserDynamicTesting()
    );
    // Then we find all the tests.
    const context = require.context('./', true, /\.spec\.ts$/);
    // And load the modules.
    context.keys().map(context);
    
  6. Add this new file src/tsconfig.spec.json:

    {
      "extends": "../tsconfig.json",
      "compilerOptions": {
        "outDir": "../out-tsc/spec",
        "baseUrl": "./",
        "module": "commonjs",
        "types": [
          "jasmine",
          "node"
        ]
      },
      "files": [
        "test.ts"
      ],
      "include": [
        "**/*.spec.ts",
        "**/*.d.ts"
      ]
    }
    

Now you should be able to run ng test and see your tests run.

Hope this helps someone.

Jeroen
  • 60,696
  • 40
  • 206
  • 339