Karma error: Can't find variable: angular - javascript

I'm trying for a week run karma in a project. I've follow this tutorial AngularJS Unit Test but when run karma start the console shows this error:
PhantomJS 2.1.1 (Linux 0.0.0) ERROR
ReferenceError: Can't find variable: angular
at /home/user/workspace/UnitTest/app/app.js:1
I thought the problem was in my project, so i've created a new one and the error persists.
My karma.conf.js is
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'app/*.js',
'tests/*.js',
'node_modules/angular/angular.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-mocks/angular-mocks.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
// web server port
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
customLaunchers: {
Chrome_without_security: {
base: 'PhantomJS',
flags: ['--disable-web-security']
}
},
singleRun: false,
concurrency: Infinity
})
}
and app.js
angular.module('MyApp', [])
.filter('reverse',[function(){
return function(string){
return string.split('').reverse().join('');
}
}])
I've tried to change the node version too, but it isn't worked.

The solution was put the angular imports before the app files like this:
files: [
'node_modules/angular/angular.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-mocks/angular-mocks.js',
'app/*.js',
'tests/*.js'
]

Related

Angular 6 Unit testing : how to use test.ts for running karma tests

Under my Angular 6 app , i ve this config
karma.conf.js:
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'),
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
browserDisconnectTimeout: 10000,
browserDisconnectTolerance: 3,
browserNoActivityTimeout: 60000,
flags: [
'--disable-web-security',
'--disable-gpu',
'--no-sandbox'
],
singleRun: true,
concurrency: Infinity
});
};
An i ve a file , test.ts ; which is supposed to configurate the test running :
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed } from '#angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '#angular/platform-browser-dynamic/testing';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /my-component.component.spec.ts/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();
i may let me filter file to be tested
for example i want to run this one : my-component.component.spec.ts
But that it not running , and it seems that it lacks some config in the karma.conf to run the test.ts
Sugesstions ?
change this line
const context = require.context('./', true, /my-component.component.spec.ts/);
with this
const context = require.context('./', true, /my-component\.component\.spec\.ts$/);
to avoid the special character '.'

Reflect.getOwnMetadata is not a function with karma-typescript

I am trying to unit test (with Karma + Jasmine + karma-typescript) my TypeScript project. The project structure is as follows:
root
|- src/*.ts //all TypeScript source files
|- tests/unit/*.spec.ts //all spec (test) files
|- karma.conf.js
|- tsconfig.json
My karma.conf.js looks like following:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', "karma-typescript"],
karmaTypescriptConfig: {
tsconfig: "./tsconfig.json"
},
files: [
'src/*.ts',
'tests/**/*Spec.ts'
],
exclude: [],
preprocessors: {
"**/*.ts": ["karma-typescript"]
},
reporters: ["progress", "karma-typescript"],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity
})
}
My spec file looks like below:
import 'aurelia-polyfills'; //<- importing this, as the project have dependency on Aurelia
// import "babel-polyfill";
import "reflect-metadata";
import "jasmine";
import { Utility } from './../../src/Utility';
describe("this is a try to set up karma-jasmine-webpack test (TS)", () => {
it("utility_test", () => {
const result = Utility.doSomething();
const expected = Expected_Result;
expect(result).toEqual(expected);
});
});
But when I run karma start, I get
Chrome 55.0.2883 (Windows 10 0.0.0) ERROR
Uncaught TypeError: Reflect.getOwnMetadata is not a function
at C:/Users/spal/AppData/Local/Temp/karma-typescript-bundle-16376WqjdFvsYtjdI.js:2325
I assume, that it is because of pollyfill(s) is/are not being loaded in the browser. However, I have imported aurelia-pollyfills in my spec file.
Please suggest how this can be corrected.
Update: Anyone looking at this for answer, might also face issues with source map (Error: Could not find source map for:'') from karma-remap-istanbul trying to generate coverage report.
One way to avoid this problem is to simply remove the problematic reporter plugin. For example, change reporters: ['mocha', 'coverage', 'karma-remap-istanbul'] to reporters: ['mocha', 'coverage'].
Other solution would be to generate the source maps. In case you can't specify the same in your tsconfig.json, you can specify that in karma.conf.js if you are using karma-typescript:
karmaTypescriptConfig: {
tsconfig: "./tsconfig.json",
compilerOptions: {
sourceMap: true
}
}
Lastly, I ended up with reporters: ["mocha", "karma-typescript"], as it shows which test passed, and which failed, as well as generate a coverage report.
You are probably missing the reflect-metadata import:
$ npm install --save-dev reflect-metadata
Then add the following to your files:
files: [
{ pattern: "node_modules/reflect-metadata/Reflect.js", include: true },
{ pattern: "src/*.ts", include: true },
{ pattern: "tests/**/*Spec.ts", include: true }
]

jasmine error when I inject a Factory

I ran a jasmine test over angular js, and i get the next error:
PhantomJS 2.1.1 (Linux 0.0.0) test_servicioCalculadora should provide
a version FAILED
/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:13218:53
forEach#/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:9168:24
loadModules#/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:13178:12
createInjector#/home/ivan/workspace/mobile.trackphone/www/lib/ionic/js/ionic.bundle.js:13104:22
workFn#/home/ivan/workspace/mobile.trackphone/www/lib/angular-mocks/angular-mocks.js:3074:60
loaded#http://localhost:9876/context.js:151:17
I tried to change the routes, inject other service, and it's not working too
I ran other case like
it("compara un valor con otro", function () {
var pi = 3.1415926,
e = 2.78;
expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});
and this's working fine.
This is my test file
describe("test_servicioCalculadora", function () {
var calcu;
beforeEach(module('starter'));
it('should provide a version', inject(function(version) {
expect(version).toEqual('v1');
}));
});
my index.js is
var app = angular.module('starter', ['ionic', 'LocalStorageModule', 'btford.socket-io', 'angularMoment', 'ngCordova', 'ngAudio']);
app.value('version', 'v1');
my karma.config.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'../www/lib/ionic/js/ionic.bundle.js',
'../www/lib/angular-mocks/angular-mocks.js',
'../www/js/index.js',
'../tests/**/*-test.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_ERROR,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false,
concurrency: Infinity
})
};
You are trying to inject a value. Should be a service or a factory.
e.g.
beforeEach(module('some.service', function($provide){
var log = {
info: function(data){
console.log(data);
}
}
$provide.value('$log', log);
});
beforeEach(inject(function(_serviceName_){
serviceName = _serviceName_;
}));
it("Actual test", function(){
serviceName.performAction();
});
See the example, first is the module where you can set some values. Then is the service or factory at the end the test.
This mean that the value of log will be injected on serviceName when is used on the actual test.
Hope this help to clarify.

Angular 2 testing karma with webpack Can't find variable: Map

I am trying to test my directive with karma and webpack.
This is the karma config file
module.exports = function (config) {
config.set({
basePath: './',
frameworks: ["jasmine"],
files: [
{
pattern: 'directive.spec.ts',
watched: false
}],
exclude: [],
preprocessors: {
'directive.spec.ts': ['webpack', 'sourcemap']
},
webpackServer: {
noInfo: true
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: [
"PhantomJS"
],
singleRun: true,
reporters: ['mocha'],
webpack: {
resolve: {
extensions: ['', '.ts', '.js'],
modulesDirectories: ['node_modules', '.'],
},
module: {
loaders: [{
test: /\.ts$/,
loader: 'awesome-typescript-loader'
}]
},
stats: {
colors: true,
reasons: true
},
debug: true,
devtool: 'inline-source-map'
}
});
};
And the directive.spec.ts:
import { MyDirective } from './directive';
import {TestComponent} from './test';
import {
async,
inject,
TestBed,
} from '#angular/core/testing';
describe('TestComponent', () => {
let fixture: any;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [ TestComponent, MyDirective]
})
.createComponent(TestComponent);
fixture.detectChanges();
});
it('should work', () => {
expect(true).toBe(true);
});
But when I am trying to run my test I am getting this error:
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR ReferenceError: Can't find
variable: Map at directive.spec.ts:1380
What am I missing here?
Please follow these steps. It worked for me:
1) Create a "karma-main.js" file with following code
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
var appContext = require.context('<Source code root folder>', true, /\.spec\.ts/); // Assuming test case files ends with spec.ts
appContext.keys().forEach(appContext);
var testing = require('#angular/core/testing');
var browser = require('#angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
2) Your karma.conf.js file should look like
var webpackConfig = require('./webpack.config')
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
plugins: [
'karma-jasmine',
'karma-PhantomJS-launcher',
'karma-webpack'
],
webpack: webpackConfig,
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
{ pattern: '<relative path to karma-main.js>', watched: false }
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'<relative path to karma-main.js>': ['webpack']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
Here is my guess: somewhere in the code you use a class Map which appeared in ES6. But PhantomJS doesn't know about this class yet since it's something too new.
So there are 3 choices:
Get rid of usage of Map and use only current JS features (like Object properties) - the cleanest approach.
Use transpiler for transforming your ES6 code into ES5 that's well understood by modern browser. This has huge disadvantages as it will mess with your line numbers and you may have to sacrifice the possibility to debug some of the code.
Use polyfills that implement ES6 features as functions in external libraries (as Sachin Gaur suggested)

Grunt, Jasmine, Phantom, React Unit Testing: React throws on ReactElementValidator

I'm using Grunt to run Jasmine unit tests with Phantom.
Grunfile.js
module.exports = function (grunt)
{
"use strict";
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-karma');
grunt.initConfig(
{
pkg: grunt.file.readJSON('package.json'),
browserify: {
dev: {
files: {
'test-output.js':['src/methods.js']
},
options: {
browserifyOptions: {
debug: true
}
}
}
},
karma:
{
unit:{
configFile:"karma.conf.js"
}
}
});
};
with this Karma config file
module.exports = function(config)
{
config.set({
basePath: '',
frameworks: ['browserify', 'jasmine'],
files: [
'myDir/*.js'
],
exclude: [
],
preprocessors: {
'myDir/*.js':['browserify','reactify']
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
browserify: {
debug: true,
transform: []
},
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine','karma-bro'],
singleRun: true
});
};
React is installed locally as a package in the node_modules folder. I can grunt browserify and everything gets bundled into test-ouput.js as expected, but when I do grunt karma I get the error:
TypeError: 'undefined' is not a function (evaluating 'ReactElementValidator.createElement.bind
If I inspect the test-ouput.js file I can see that the ReactElementValidator.createElement.bind function is inside of the bundle. Any ideas what could be causing this?
This a know issue with phantomJS < 2.0. To fix this simply install phantomjs polyfill like this:
npm install --save-dev phantomjs-polyfill
And add it to the config like this.
files: [
'node_modules/phantomjs-polyfill/bind-polyfill.js',
'myDir/*.js'
]
I hope this helped.

Categories