Testing module cannot resolve the tested module [Angular4, Karma, Jasmine]

I have a small TypeScript application built as a demo project. It uses Angular 4, Karma, Webpack 2 and Jasmine.

The app is running successfully and I can run it in the browser.

The tests don't work when I run karma start

on the command line, I see the following message:

Mistake in. /app/welcome/app.welcome.spec.ts Module not found: Error: Unable to resolve './app.welcome' in 'D: \ ng-ts-demo \ app \ welcome'
@. / app / welcome / app .welcome.spec.ts 4: 20-44
@. / app.spec.ts
@. / app / test-main.ts

It's weird that the app.welcome.ts file is in the same directory as app.welcome.spec.ts, but it still can't find it! From the message you can see that the problem is caused by the fact that the test-main.ts file does not load * .ts files, but only * .spec.ts files.

I've followed the official Angular 4 / Webpack guide here and I don't seem to see anything critical.

Here is my test-main.ts file:

Error['stackTraceLimit'] = Infinity;

import 'core-js/es7/reflect';
import 'reflect-metadata';
import 'zone.js';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/proxy';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';

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

let appContext = require.context('./', true, /\.spec\.ts/); // is this line the problem?

appContext.keys().forEach(appContext);

TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());

      

Here is my Karma.conf.js file:

'use strict';

const webpack = require('webpack');

module.exports = function(config) {
    config.set({

        basePath: '',
        frameworks: ['jasmine'],
        files: [
            { pattern: './app/test-main.ts' }
        ],
        exclude: [],
        preprocessors: {
            './app/test-main.ts': ['webpack', 'sourcemap']
        },
        reporters: ['progress'],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: false,
        browsers: ['ChromeHeadless'],
        customLaunchers: {
            ChromeHeadless: {
                base: 'Chrome',
                flags: [
                  '--headless',
                  '--remote-debugging-port=9222',
                  '--disable-gpu',
                  '--disable-plugins',
                  '--window-size=0,0',
                  '--window-position=-9999,0'
                ],
            },
        },
        singleRun: true,
        concurrency: Infinity,
        webpack: {
            module: {
                rules: [{
                    test: /\.ts$/,
                    use: [
                        {
                            loader: 'awesome-typescript-loader',
                            options: {
                                configFileName: './tsconfig.json'
                            }
                        },
                        'angular2-template-loader'
                    ]
                }]
            },
            devtool: 'inline-source-map',
            plugins: [
                new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/, './app')
            ]
        },
        webpackMiddleware: {
            stats: 'errors-only'
        },
        webpackServer: {
            noInfo: true
        }
    });
}

      

Here is the app.welcome.spec.ts file:

import { TestBed }            from '@angular/core/testing';
import { WelcomeComponent }   from './app.welcome';

describe('The Welcome component', function () {

    let component: WelcomeComponent;

    beforeEach(function() {
        TestBed.configureTestingModule({
            declarations: [WelcomeComponent]
        });

        let fixture = TestBed.createComponent(WelcomeComponent);
        component = fixture.componentInstance;
    });

    it('should be a component', function() {
        expect(component).toBeDefined();
    });

    it('should have a welcome message', function () {
        expect(component.welcomeMessage).toEqual('Welcome to TypeScript!');
    });

});

      

And here is the app.welcome.ts module (which is in the same folder as the spec file, but mysteriously cannot be found):

import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: '<h1>{{welcomeMessage}}</h1>',
})

export class WelcomeComponent {
    welcomeMessage = 'Welcome to TypeScript!';
}

      

+1


source to share


1 answer


In the course of this work, it was necessary to solve a number of problems. The first fix was to add the permission config webpack

to the config in the karma.conf.js file:

resolve: {
    extensions: ['.js', '.ts']
},

      

This solved the problem of my test files not being able to import the files they were testing.

This leads to the second problem - the test files themselves are not being executed (I could see Executed 0 of 0 ERROR

in the command line when running the test. Debugging the test (by installing singleRun

on false

and changing the browser from ChromeHeadless

to normal) Chrome

showed an error in the console:

Refused to execute script from http: // localhost: 9876 / base / test-main.ts ' because its MIME type ('video / mp2t') is not executable.



This is a new issue affecting Chrome 55+ and there is a slightly hacky fix that is needed now; I had to add this to the karma.conf.js file (but not in the webpack

config section ):

mime: {
    'text/x-typescript': ['ts']
}, 

      

This tip was found in this issue . Finally, the tests are already running :)

Now, to get coverage that works as well ...

+1


source







All Articles