2

My team updated the Rails version of our application to 5.1 so we could use Webpacker, a wrapper to use Webpack with Rails and then use Angular 2 properly.

We started setting up the test suite for the Angular 2 modules using Karma + Jasmine + Webpack following this article.

If I write simple test cases, without Angular Component, TestBed and ComponentFixture, everything looks fine. However, if I try to import Angular modules and test some components, Karma raises the following error message for every component and module:

ERROR in ./app/javascript/app/app.module.ts
Module parse failed: /[application path omitted]/app/javascript/app/app.module.ts Unexpected character '@' (17:0)
You may need an appropriate loader to handle this file type.
| import { AppRoutingModule } from './app-routing.module';
| 
| @NgModule({
|   imports: [
|     BrowserModule,

The project structure is:

- app
-- ...
-- javascript (webpacker create this folder in the first time running)
---- app (where all modules are stored)
------ ...
------ app.routing.module.ts
------ app.component.ts
------ app.module.ts
------ echo.pipe.ts (a file created just to test the Karma suite)
---- packs
---- test
------ echo.pipe.spec.ts
------ main.js (entry point of tests)
------ main.spec.ts

The karma.conf.js file:

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      { pattern: './app/javascript/app/**/*.ts', watched: false, served: true },
      { pattern: './app/javascript/test/main.js', watched: false }
    ],
    plugins: [
      require('karma-webpack'),
      require('karma-jasmine'),
      require('karma-phantomjs-launcher'),
      require('karma-chrome-launcher'),
      require('karma-sourcemap-loader'),
      require('karma-babel-preprocessor'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter')
    ],
    exclude: [
    ],
    preprocessors: {
      'app/javascript/**/*.ts': ['webpack', 'sourcemap'],
      'app/javascript/test/main.js': ['webpack', 'sourcemap']
    },
    mime: { 'text/x-typescript': ['ts','tsx'] },
    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['Chrome'],
    singleRun: true,
    concurrency: Infinity
  })
}

The echo.pipe.ts file:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'echo'
})
export class EchoPipe implements PipeTransform {
  transform(value: any): any {
    return value;
  }
}

The main.js file:

describe('Meaningful Test', () => {
    it('1 + 1 => 2', () => {
        expect(1 + 1).toBe(2);
    });
});

require('./main.spec.ts');

The main.spec.ts file:

import 'core-js/es6';
import 'core-js/es7/reflect';

import 'zone.js/dist/zone';
import 'zone.js/dist/proxy';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import 'zone.js/dist/jasmine-patch';

import 'rxjs/Rx';

import { TestBed } from '@angular/core/testing';
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';

TestBed.initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);

describe('Meaningful Test 2', () => {
    it('1 + 1 => 2', () => {
        expect(1 + 1).toBe(2);
    });
});

The echo.pipe.spec.ts file:

import { Component }                        from '@angular/core';
import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import { By }                               from '@angular/platform-browser';
import { DebugElement }                     from '@angular/core';

import { EchoPipe } from '../app/echo.pipe';

describe('EchoPipe', () => {

  let comp:    EchoPipe;
  let fixture: ComponentFixture<EchoPipe>;
  let de:      DebugElement;
  let el:      HTMLElement;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ EchoPipe ],
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(EchoPipe);

    comp = fixture.componentInstance; 

    comp.name = 'foo';
  });

  it('works well', () => {
    fixture.detectChanges();

    el = fixture.debugElement.nativeElement as HTMLElement; 

    expect(el.querySelector('p').textContent).toBe('foo');
  });
});

const context = require.context('./', true, /\.spec\.ts$/);
context.keys().map(context);

0 Answers0