I have a nw.js native application with angular.js inside. My app bundled with webpack and contains native node.js modules. My entry point is index.js file that I organized like this:
var gui = require('nw.gui'); var angular = require('angular'); require('./app.css'); // other modules var myApp = angular.module('myApp', [ 'ngRaven', 'ngMaterial', 'ngMessages' ]).constant( 'fs', require('fs') ) require('./services')(myApp); require('./directives')(myApp); require('./factories')(myApp); require('./filters')(myApp); require('./controllers')(myApp); require('./app.js')(myApp); My webpack config looks like this:
const path = require('path'); const config = { entry: [ './app/index.js' ], output: { path: path.resolve(__dirname, 'app'), filename: 'bundle.js' }, devtool: "source-map", target: 'node-webkit', module:{ // css, html loaders }, node: { os: true, fs: true, child_process: true, __dirname: true, __filename: true } }; module.exports = config; So every dependency include Node.js native modules like fs, path, child_process bundled in one big file bundle.js that i include in html and then package my nw.js app. So my app structure looks like:
my_project: --app ----controllers ------welcome --------welcome.js // Page controller --------welcome.html // Page HTML ------index.js // here I include each page controller ----app.js // My angular app initialization ----index.js // here I include all dependencies I'm trying to run tests with this structure. I tried karma+jasmine, karma+mocha, tried different configurations, my last one looks like:
module.exports = function (config) { config.set({ basePath: '', frameworks: ['jasmine'], files: [ 'app/bundle.js', 'app/**/*spec.js' ], exclude: [], preprocessors: { 'app/bundle.js': ['webpack'] }, reporters: ['progress'], port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, browsers: ['ChromeHeadlessNoSandbox'], customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', flags: ['--no-sandbox'] } }, singleRun: true, webpack: { // you don't need to specify the entry option because // karma watches the test entry points // webpack watches dependencies // ... remainder of webpack configuration (or import) }, webpackMiddleware: { // webpack-dev-middleware configuration // i.e. noInfo: true, // and use stats to turn off verbose output stats: { // options i.e. chunks: false } } }); }; But my tests still not see the angular application.
describe('Welcome page', function() { beforeEach(angular.mock.module('WelcomePageCtrl')); }); P.S I don't require exactly karma and jasminne, so any solution will be appreciated. I just want to cover my project with tests
1 Answers
Answers 1
I have gone through something similar myself. I don't think you need the bundle.js for your tests.
Here is how would do it:
I assume your controller/service/etc implementation is as follows:
/* app/controller/welcome.js */ module.exports = function(app) { return app.controller("MyCtrl", function($scope) { $scope.name = "lebouf"; }); }; I like my test code to sit right beside the code I'm testing (Welcome.spec.js in the same directory as Welcome.js). That test code would look like so:
/* app/controller/welcome.spec.js */ beforeEach(function() { var app = angular.module("myApp", []); //module definition require("./welcome")(app); }); beforeEach(mockModule("myApp")); describe("MyCtrl", () => { var scope = {}; beforeEach(mockInject(function($controller) { $controller("MyCtrl", { $scope: scope }); })); it("has name in its scope", function() { expect(scope.name).to.equal("not lebouf"); //the test will fail }); }); Except, this is an angular controller we're testing and it's not that simple. We need the angular object itself. So lets set it up. I'll explain why it is done how it is done next:
/* test-setup.js */ const jsdom = require("jsdom").jsdom; //v5.6.1 const chai = require("chai"); global.document = jsdom("<html><head></head><body></body></html>", {}); global.window = document.defaultView; global.window.mocha = true; global.window.beforeEach = beforeEach; global.window.afterEach = afterEach; require("angular/angular"); require("angular-mocks"); global.angular = window.angular; global.mockInject = angular.mock.inject; global.mockModule = angular.mock.module; global.expect = chai.expect; console.log("ALL SET"); And we'll run the tests as:
node_modules/.bin/mocha ./init.js app/**/*.spec.js #or preferably as `npm test` by copying the abev statement into package.json extra info
Here is how init.js is setup as is:
jsdom: f yourequire("angular/angular")you'll see that it needs awindowinstance.jsdomcan createdocuments andwindows and so on without a web browser!window.mocha: we needangular-mocksto populate ourangularwith the necessary utilities. But if you look at the code you'll notice thatwindow.mocha || window.jasmineneeds to betrue. Thats whywindow.mocha = true`window.beforeEach,window.afterEach: the same reason as above; becauseangular-mocks.jsdemands it.- I set some global variables that I plan to use commonly in my tests:
angular,expect,mockInject,mockModule.
Also these may provide some additional information:
0 comments:
Post a Comment