javascript - Angular.js+nw.js+webpack+karma+jasmine如何测试

标签 javascript angularjs node.js karma-jasmine

我有一个 nw.js native 应用程序 angular.js里面。我的应用程序与 webpack 捆绑在一起并包含 native node.js 模块。我的入口点是我这样组织的 index.js 文件:

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);

我的 webpack 配置如下所示:

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;

因此每个依赖项都包含 Node.js 原生模块,如 fspathchild_process 捆绑在一个大文件中 bundle.js 我包含在 html 中,然后打包我的 nw.js 应用程序。所以我的应用程序结构如下所示:

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 

我正在尝试使用此结构运行测试。我尝试了 karma+jasmine,karma+mocha,尝试了不同的配置,我的最后一个看起来像:

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
            }
        }
    });
};

但我的测试仍然没有看到 Angular 应用程序。

describe('Welcome page', function() {
    beforeEach(angular.mock.module('WelcomePageCtrl'));
});

P.S 我不完全需要 karmajasminne,所以任何解决方案都会受到赞赏。我只想用测试覆盖我的项目

最佳答案

我自己也经历过类似的事情。我认为您的测试不需要 bundle.js

这是如何做到的:

我假设您的 Controller /服务/等实现如下:

    /* app/controller/welcome.js */
    module.exports = function(app) {
        return app.controller("MyCtrl", function($scope) {
            $scope.name = "lebouf";
        });
    };

我喜欢我的测试代码紧挨着我正在测试的代码(Welcome.spec.jsWelcome.js 位于同一目录中)。该测试代码如下所示:

/* 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
    });
});

除了,这是我们正在测试的 Angular Controller ,它并不那么简单。我们需要 angular 对象本身。所以让我们设置它。我将解释为什么它是如何完成的:

/* 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");

我们将运行测试:

node_modules/.bin/mocha ./init.js app/**/*.spec.js
#or preferably as `npm test` by copying the abev statement into package.json

额外信息

下面是 init.js 的设置方式:

  1. jsdom:如果您require("angular/angular"),您会发现它需要一个window 实例。 jsdom 可以在没有网络浏览器的情况下创建文档窗口等!
  2. window.mocha:我们需要 angular-mocks 来使用必要的实用程序填充我们的 angular。但是if you look at the code你会注意到 window.mocha || window.jasmine 需要为 true。这就是为什么window.mocha = true`
  3. window.beforeEach, window.afterEach:同上道理;因为 angular-mocks.js 需要它。
  4. 我设置了一些我计划在测试中常用的全局变量:angularexpectmockInjectmockModule

此外,这些可能会提供一些额外的信息:

关于javascript - Angular.js+nw.js+webpack+karma+jasmine如何测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51283174/

相关文章:

javascript - 在 HTML 中调用匿名函数

javascript - Angular 依赖注入(inject)

javascript - AngularJS ng-repeat 唯一的对象数组

node.js - Passport 注册本地返回 "Missing Credentials"

javascript - codeSandBox (React/Node) 的 Http 请求错误

javascript - deepstream 列表订阅数据

javascript - 如何为不规则时间图创建平均线?

css - Bootstrap 会在自定义指令元素内创建间距吗?

javascript - iOS 7+ 向后滑动手势与 stateChange 动画冲突

javascript - Angular - $routeParams.itemID 用于加载domain.com/:itemID ALMOST WORKING?