I am struggle with create proper unit tests for the angularjs (v1.4.9) application which contains both javascript files (with jasmine tests) and typescript files (with no tests at all, now I am trying to use Mocha, but it can be any framework).
Hence it hybrid and an old angularjs without modules, I decided to compile all .ts to one bundle.js
file, due to avoid files ordering problem (which occurs when I have single .js file per .ts and inject it with gulp task to index.html
).
My tsconfig.js:
{
"compileOnSave": true,
"compilerOptions": {
"noImplicitAny": false,
"removeComments": false,
"outFile": "./wwwroot/bundle.js",
"sourceMap": true,
"inlineSources": true,
"module": "amd",
"moduleResolution": "node",
"target": "es5",
"sourceRoot": "./wwwroot"
},
"include": [
"wwwroot/app/**/*"
],
"exclude": [
"node_modules/**/*",
"tests/**/*"
]
}
example of tested class:
///<reference path="../models/paymentCondition.model.ts"/>
///<reference path="../../../../../node_modules/@types/angular/index.d.ts"/>
'use strict';
module PaymentCondition {
export class ConnectedCustomersListController {
name: string;
static $inject = ['paymentCondition'];
constructor(private paymentCondition: PaymentConditionModel) {
this.name = paymentCondition.Name;
this.bindData();
}
bindData() {
// do something
}
}
angular
.module('app.paymentConditions')
.controller('ConnectedCustomersListController', ConnectedCustomersListController);
}
My module declaration:
///<reference path="../../../../node_modules/@types/angular/index.d.ts"/>
'use strict';
module PaymentCondition {
angular.module('app.paymentConditions', ['ui.router', 'ui.bootstrap']);
}
and I am 'injecting' this module to main module file, which is already in javascript- App.module.js
.:
(function () {
'use strict';
var module = angular.module('app', [
'app.paymentCondition',
'ui.router',
'ui.bootstrap',
]);
})();
and finally my test class:
///<reference path="../../../node_modules/@types/angular/index.d.ts"/>
///<reference path="../../../wwwroot/app/domain/paymentConditions/connectedCustomersList/connectedCustomersList.controller.ts"/>
///<reference path="../../../node_modules/@types/angular-mocks/index.d.ts"/>
import { expect } from 'chai';
import "angular-mocks/index";
import * as angular from "angular";
describe("app.paymentConditions.connectedCustomersList", () => {
var mock;
// inject main module
beforeEach(angular.mock.module('app.paymentConditions'));
beforeEach(angular.mock.inject(($controller: ng.IControllerService) => {
mock = {
connectedCustomersListModel: {
columnDefinitions() {
}
},
paymentCondition: {},
createController(): PaymentCondition.ConnectedCustomersListController {
return $controller<PaymentCondition.ConnectedCustomersListController >('ConnectedCustomersListController', {
connectedCustomersListModel: mock.connectedCustomersListModel,
});
}
};
}));
describe("ConnectedCustomersListController", () => {
var controller: PaymentCondition.ConnectedCustomersListController;
beforeEach(() => {
controller = mock.createController();
});
it("should be defined", () => {
expect(controller).not.undefined;
});
});
});
when I am trying to run mocha
tests with command:
./node_modules/.bin/mocha --compilers ts:ts-node/register ./tests/**/*.spec.ts
I have this exception:
ReferenceError: define is not defined
at Object.<anonymous> (C:\Projects\App.Frontend\EasyFrontend\src\EasyFrontend\tests\paymentConditions\connec
edCustomersList\connectedCustomersList.controller.spec.ts:5:1)
at Module._compile (module.js:643:30)
at Module.m._compile (C:\Projects\App.Frontend\EasyFrontend\src\EasyFrontend\node_modules\ts-node\src\index.
s:422:23)
at Module._extensions..js (module.js:654:10)
at Object.require.extensions.(anonymous function) [as .ts] (C:\Projects\App.Frontend\EasyFrontend\src\EasyFr
ntend\node_modules\ts-node\src\index.ts:425:12)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at C:\Projects\App.Frontend\EasyFrontend\src\EasyFrontend\node_modules\mocha\lib\mocha.js:231:27
at Array.forEach (<anonymous>)
at Mocha.loadFiles (C:\Projects\App.Frontend\EasyFrontend\src\EasyFrontend\node_modules\mocha\lib\mocha.js:2
8:14)
at Mocha.run (C:\Projects\App.Frontend\EasyFrontend\src\EasyFrontend\node_modules\mocha\lib\mocha.js:536:10)
at Object.<anonymous> (C:\Projects\App.Frontend\EasyFrontend\src\EasyFrontend\node_modules\mocha\bin\_mocha:
82:18)
at Module._compile (module.js:643:30)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Function.Module.runMain (module.js:684:10)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
npm ERR! Test failed. See above for more details.
I know it is because I am using amd
module to compile my typescript to one js file, but I don't really know how to fix it. Or if it can't be fixed maybe you have some advices how to 'marrige' the type script to existing AngularJs solution.
Ps. I am using mocha with backed typescript compiler, because I have no idea how to run jasmine tests with this combination.
My Index.html:
<!DOCTYPE html>
<html>
<head ng-controller="AppCtrl">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta lang="da" />
<title>{{ Page.title() }}</title>
<!-- endbuild -->
<!-- inject:css -->
<link rel="stylesheet" type="text/less" href="less/site.less" />
<!-- endinject -->
<!-- build:remove -->
<script src="less/less.js"></script>
<!-- endbuild -->
<!-- bower:js -->
<script src="lib/jquery/dist/jquery.js"></script>
<script src="lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="lib/angular/angular.js"></script>
<script src="lib/toastr/toastr.js"></script>
<script src="lib/angular-ui-router/release/angular-ui-router.js"></script>
<script src="lib/angular-ui-grid/ui-grid.js"></script>
<script src="lib/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="lib/sugar/release/sugar-full.development.js"></script>
<script src="lib/ng-context-menu/dist/ng-context-menu.js"></script>
<script src="lib/ng-messages/angular-messages.js"></script>
<script src="lib/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
<script src="lib/bootstrap-datepicker/dist/locales/bootstrap-datepicker.da.min.js"></script>
<script src="lib/angular-ui-tree/dist/angular-ui-tree.js"></script>
<script src="lib/angular-sanitize/angular-sanitize.js"></script>
<script src="lib/color-hash/dist/color-hash.js"></script>
<script src="lib/angular-ui-mask/dist/mask.js"></script>
<script src="lib/google-maps-js-marker-clusterer/src/markerclusterer.js"></script>
<script src="lib/ngDraggable/ngDraggable.js"></script>
<script src="lib/requirejs/require.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- build:site_js js/site.min.js -->
<!-- inject:app:js -- >
<script src="bundle.js"></script>
<script src="app/app.module.js"></script>
<script src="app/app.route.config.js"></script>
<script src="app/app.module.config.js"></script>
<script src="app/app.constants.js"></script>
<script src="app/app.appCtrl.js"></script>
<!-- endinject -->
<!-- endbuild -->
<!-- endbuild -->
<!-- build:remove -->
<script src="init.js"></script>
<!-- endbuild -->
</head>
<body>
<div class="fluid-container">
<ee-global-context-menu></ee-global-context-menu>
<ui-view></ui-view>
</div>
</body>
</html>