Jasmine breaks when instantiating class - unit-testing

I'm trying to write tests for our Angular 2 app with Jasmine. Followed a few tutorials, tried a lot. It works with basic tests, but once I make an instance of a component or try to mock it I just get no testresults. According to Angular Doc it's 'That's Jasmine saying "things are so bad that I'm not running any tests."'
Strangely enough, BlobViewModel does work. Whenever I comment or delete the 'this.const = new Constants();' it works again. Tried with multiple classes, always get the same results.. No logs/errors in chrome.
We're using Angular RC4 with Jasmine 2.4.1.
This is my .spec file:
import {Component, OnInit, OnDestroy } from "#angular/core";
import {Router} from '#angular/router';
import { Constants } from './shared/app.constants';
describe('component test', () => {
beforeEach(function () {
this.const = new Constants(); // THIS BREAKS IT
});
it('Tests', () => {
//Tests come here
//this.const.Signalr();
});
});
describe('1st tests', () => {
it('true is true', () => expect(true).toEqual(true));});
describe('BlobViewModel', () => {
var id = 1;
var localhost = "http//localhost";
var fullpath = "http//fullpathtoapplication.com";
var printername = "Printy print";
var papersize = "A4";
var blobmodel = new BlobViewModel(id, localhost, fullpath, printername, papersize);
it('BlobviewModel aanmaken', () => {
expect(blobmodel.ID).toEqual(id);
expect(blobmodel.FullLocalUrl).toEqual(localhost);
expect(blobmodel.FullPath).toEqual(fullpath);
expect(blobmodel.PrinterName).toEqual(printername);
expect(blobmodel.PaperSize).toEqual(papersize);
});
});
HTML file for the .spec runner:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Ng App Unit Tests</title>
<link rel="stylesheet" href="../js/jasmine-core/lib/jasmine-core/jasmine.css">
<script src="../js/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="../js/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="../js/jasmine-core/lib/jasmine-core/boot.js"></script>
</head>
<body>
<!-- #1. add the system.js library -->
<script src="../js/systemjs/dist/system.src.js"></script>
<script src="../app/Systemjs.config.js"></script>
<script>
// #2. Configure systemjs to use the .js extension
// for imports from the app folder
System.config({
packages: {
'../app': { defaultExtension: 'js' }
}
});
// #3. Import the spec file explicitly
System.import('../app/file.spec.js')
// #4. wait for all imports to load ...
// then re-execute `window.onload` which
// triggers the Jasmine test-runner start
// or explain what went wrong.
.then(window.onload)
.catch(console.error.bind(console));
</script>
</body>
</html>

In the end I figured it out, had to import the "Reflect-metadata" package in the html file:
<script src="../js/reflect-metadata/Reflect.js"></script>

Related

Why is Mocha & Chia unit test failing to catch expected error in web-component constructor?

I have a unit testing set up using Mocha and Chia run in a Chrome browser as shown below. To enforce the Component class' static htmlTagName property, I am using an error in the Component base-class that gets thrown if the htmlTagName property is not overwritten by a child class. The problem that I am encountering is that the error thrown in the constructor does not appear to be caught by chia.assert.throw(...) instead it causes the test to fail as shown in the link below. The behavior I expected to see is that chia catches the expected error and the test passes. I have included the relevant code below.
Unit-test error result image
<!DOCTYPE html>
<!-- index.html -->
<html>
<head>
<title>Mocha Tests</title>
<link rel="stylesheet" href="../../node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="../../node_modules/mocha/mocha.js"></script>
<script src="../../node_modules/chai/chai.js"></script>
<script type="module" class="mocha-init">mocha.setup('bdd')</script>
<!-- load code you want to test here -->
<!-- load your test files here -->
<script type='module' src="./objective-styles.test.js"></script>
<script type='module' src="./base-classes.test.js"></script>
<script type='module' src="./calendar-widget.test.js"></script>
<script type="module">
mocha.run();
</script>
</body>
</html>
//base-classes.ts
export class Component extends HTMLElement {
static htmlTagName: string | undefined;
constructor() {
super();
// Enforce classes having htmlTagName
if(!this.htmlTagName) {
throw (`${this.constructor.name} htmlTagName property is undefined`);
}
}
get htmlTagName() {
return this.constructor.htmlTagName;
}
set htmlTagName(htmlTagName: string) {
this.constructor.htmlTagName = htmlTagName;
}
}
// base-classes.test.ts
import { GuiTestingUtils } from "./gui-testing-utils.js";
import { Component, Widget} from "../../app/js/widgets/base-classes.js";
describe("Component test suite", ()=>{
let sandbox: HTMLDivElement;
let fakeDOM: ShadowRoot;
let style: HTMLStyleElement;
before(()=>{
// set up the sandbox
let body = document.querySelector('body');
sandbox = GuiTestingUtils.addSandbox(body!);
fakeDOM = sandbox.shadowRoot!;
style = document.createElement('style');
});
beforeEach(()=>{
// clean the sandbox
GuiTestingUtils.refreshSandbox(sandbox);
fakeDOM.appendChild(style);
});
after(()=>{
// tear down the sandbox
let body = document.querySelector('body');
body!.removeChild(sandbox);
});
it("Component does throw error if htmlTagName is not defined", ()=>{
// chia.assert.throw does not catch the error as expected...
customElements.define("base-component", Component);
chai.assert.throw(()=>{
document.createElement("base-component");
});
});
});

Polymer not Defined in Web Component Tester

I am trying to run two tests with web-component-tester interactively on a Polymer 2 project in Chrome v69, web-component-test v 6.5.0, and webcomponentsjs v 2.1.3. The first super basic test passes, and the second fails with the following error:
Error: Polymer is not defined flush at shop-home.test.html:36
<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>shop-home</title>
<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<script>void(0)</script>
<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="/bower_components/test-fixture/test-fixture.html">
<link rel="import" href="../shop-home.html">
</head>
<body>
<test-fixture id="basic">
<template>
<shop-home></shop-home>
</template>
</test-fixture>
<script>
suite('shop-home tests', () => {
var home;
setup(() => {
home = fixture('basic');
});
test('super basic test', (done) => {
flush(() => {
console.log('what a great test')
done();
});
});
test('load mission statement', (done) => {
flush(() => {
let ms = Polymer.dom(home.root).querySelector('mission-statement');
assert.exists(ms, 'mission statement is neither `null` nor `undefined`');
done();
});
});
});
When running via the command line the error gives more detail:
Error: Error thrown outside of test function: document.getElementById(fixtureId).create is not a function. (In 'document.getElementById(fixtureId).create(model)', 'document.getElementById(fixtureId).create' is undefined)
at shop-home.html:25, 1 failed tests, Error thrown outside of test function: document.getElementById(...).create is not a function
at shop-home.html:25
How can I prevent this and run a proper unit test?

Jasmine unit test not loading component Angular2 RC1

I can't get my jasmine unit-tests to load the a component for testing.
Webstorm is telling me that everything is good to go in terms of syntax. But when I load live-server to have the unit test load it doesn't seem to work.
I have it compiling to a test directory at root.
So here is my directory tree (abv for the ease):
-- client(src)
|-- common
|---- welcome.component.ts
|---- welcome.spec.ts
-- node_modules
-- tests(compiled spec and components)
|-- client(src)
|---- common
|------ welcome.component.ts
|------ welcome.spec.ts
--unit-tests.html
--systemjs.config.js
live server is giving me this:
GET /tests/client/common/welcome.component 404
welcome.spec.ts
/// <reference path="../../typings/main/ambient/jasmine/index.d.ts" />
import {WelcomeComponent} from './welcome.component';
describe('Welcome tests', () => {
let welcome:WelcomeComponent;
beforeEach(() => {
welcome = new WelcomeComponent('sir');
});
it('Nombre should equal sir', () => {
expect(welcome.nombre).toEqual('sir');
})
});
unit-tests.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Tests</title>
<link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
</head>
<body>
<!-- #1. add the system.js library -->
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
// #2. Configure systemjs to use the .js extension
// for imports from the app folder
System.config({
packages: {
'client': {defaultExtension: 'js'}
}
});
// #3. Import the spec file explicitly
System.import('tests/client/common/welcome.spec.js');
System.import('tests/client/common/header.spec.js')
// #4. wait for all imports to load ...
// then re-execute `window.onload` which
// triggers the Jasmine test-runner start
// or explain what went wrong.
.then(window.onload)
.catch(console.error.bind(console));
</script>
</body>
</html>
systemjs.config.js
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'tests/client', // 'dist',
'rxjs': 'node_modules/rxjs',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'#angular': 'node_modules/#angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' },
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/router-deprecated',
'#angular/testing',
'#angular/upgrade',
];
// add package entries for angular packages in the form '#angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
}
// filterSystemConfig - index.html's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
I can add more if you need me too, the header.spec works great, but it's self-container. (expect true = true, etc)
SystemJS should be loading this for the unit-tests but it does not, the site itself works great so the Welcome.component is fine. But for some reason I cannot load the unit test.
Where would I be going wrong? I feel like this is a config issue, but I am not very familiar with unit-tests.
I had a similar issue the other day, take a look at this comment. If you have a spec-bundle.js or something similar, make sure var testing and var browser is referring to RC1 and not beta.
Also, if you have this somewhere: testing.setBaseTestProviders(
browser.TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
browser.TEST_BROWSER_STATIC_APPLICATION_PROVIDERS);
this is how it should look for RC1, it was different for beta

Jasmine Testing Angular2 Components failing on #Component annotation

I have a simple test I'm trying to run through jasmine. Here are the ts files.
Unit-Test.html
<html>
<head>
<title>1st Jasmine Tests</title>
<link rel="stylesheet" href="../node_modules/jasmine-core/lib/jasmine-core/jasmine.css" />
<script src="../node_modules/systemjs/dist/system.src.js"></script>
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
<!--<script src="../node_modules/zone/lib/zone.js"></script>-->
</head>
<body>
<script>
// #2. Configure systemjs to use the .js extension
// for imports from the app folder
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
'test': { defaultExtension: 'js' },
'app': { defaultExtension: 'js' }
}
});
// #3. Import the spec file explicitly
System.import('test/test.spec')
// #4. wait for all imports to load ...
// then re-execute `window.onload` which
// triggers the Jasmine test-runner start
// or explain what went wrong
.then(window.onload)
.catch(console.error.bind(console));
</script>
</body>
</html>
test.spec.ts
import {TestComponent} from "../app/components/about/test.component"
describe('Test Component->', () => {
it('has name given in the constructor', () => {
var t1 = new TestComponent('Super Cat');
expect(t1.myValue).toEqual('Super Cat');
});
it('does not have the id given in the constructor', () => {
var t2 = new TestComponent('Super Cat');
expect(t2.myValue).not.toEqual(1);
});
});
test.component.ts NOTICE THE COMMENTED OUT COMPONENT ANNOTATION
import {Component} from 'angular2/core';
//#Component({
// selector: 'test-component',
// templateUrl: "<div></div>",
//})
export class TestComponent {
constructor(value: string) {
this.myValue = value;
}
public myValue = '';
onKey2() {
return this.myValue;
}
}
Now if I hit the unit-test.html with the #Copmonent annotation commented out I get the following result
however if I uncomment the #Component annotation line, as this is really how my components will be defined... I get the following error
Can someone please tell me why I'm getting this error. I've tried importing "reflect-metadata" as well with no success
Ok, I think I got it... I had to change the script section in my unit-test.html to the following in this exact order!! Now I just have to figure out how to pull this into a separate project
<script src="../node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="../node_modules/systemjs/dist/system.src.js"></script>
<script src="../node_modules/rxjs/bundles/Rx.js"></script>
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="../node_modules/angular2/bundles/testing.dev.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>

Testing Angular With Mocha and Chai

I want to test my angular app with Yeoman which use Mocha with Phantom and Chai for assertion.
But when i run any sample test case the test case do not run properly it shows PhantomJs timed out due to missing Mocha run() call.Non angular Cases are working fine in test case.
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Mocha Spec Runner</title>
<link rel="stylesheet" href="lib/mocha/mocha.css">
</head>
<body>
<div id="mocha"></div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script src="lib/mocha/mocha.js"></script>
<script>mocha.setup('bdd')</script>
<script src="lib/chai.js"></script>
<script>
expect = chai.expect;
assert = chai.assert;
</script>
<script>
function addSum(num1, num2) {
return num1 + num2;
}
</script>
<script>
(function() {
describe('Give it some context', function() {
it('should simulate promise', inject(function ($q, $rootScope) {
assert.notStrictEqual(3, '3', 'no coercion for strict equality');
/* var deferred = $q.defer();
var promise = deferred.promise;
var resolvedValue;
promise.then(function(value) { resolvedValue = value; });
expect(resolvedValue).to.be.undefined;
// Simulate resolving of promise
deferred.resolve(123);
// Note that the 'then' function does not get called synchronously.
// This is because we want the promise API to always be async, whether or not
// it got called synchronously or asynchronously.
expect(resolvedValue).to.be.undefined
// Propagate promise resolution to 'then' functions using $apply().
$rootScope.$apply();
expect(resolvedValue).to.equal(123);*/
}));
});
})();
</script>
<!-- trigger the mocha runner -->
<script src="runner/mocha.js"></script>
</body>
</html>
Have you tried using protractor? It has been developed specifically for testing end to end angularjs apps (by the angularjs team). https://github.com/angular/protractor
It has it's own runner, which you install with:
npm install protractor -g
and then the runner is executed with:
protractor /configfile.cfg
No need for an HTML page to run the tests.
The config file is quite simple (you can see the options in the source code).
With that, you'll have the spec defined as:
// myTest.js
describe('angularjs homepage', function() {
it('should greet the named user', function() {
browser.get('http://www.angularjs.org');
element(by.model('yourName')).sendKeys('Julie');
var greeting = element(by.binding('yourName'));
expect(greeting.getText()).toEqual('Hello Julie!');
});
});