如何解决“无法在模块外部使用import语句"用angularjs运行业力单元测试时? [英] How to fix "Cannot use import statement outside a module" when running karma unit test with angularjs?

查看:60
本文介绍了如何解决“无法在模块外部使用import语句"用angularjs运行业力单元测试时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RecordsControllerTest.spec.js

RecordsControllerTest.spec.js

 // import RecordsController from '../../public/RecordsController';
import {app} from '../../public/app.js';    // without this gives "Module 'app' is not available! You either misspelled the module name or forgot to load it. "


describe('RecordsController', function() {
     //beforeEach(module('app'));
    beforeEach(angular.mock.module('app'));

    var $controller, $rootScope;

    beforeEach(inject(function(_$controller_, _$rootScope_){
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $controller = _$controller_;
        $rootScope = _$rootScope_;
    }));

    describe('$scope.grade', function() {
        it('sets the strength', function() {
            var $scope = $rootScope.$new();
            /*var controller =*/ $controller('RecordsController', { $scope: $scope });

            let grade = $scope.grade(1);
            expect(grade).toEqual('small');
        });
    });
});

package.json

package.json

{
  "name": "angular-phonecat",
  "private": true,
  "version": "0.0.0",
  "description": "A tutorial application for AngularJS",
  "repository": "https://github.com/angular/angular-phonecat",
  "license": "MIT",
  "dependencies": {
    "angular": "1.7.x",
    "angular-animate": "1.7.x",
    "angular-resource": "1.7.x",
    "angular-route": "1.7.x",
    "bootstrap": "3.3.x",
    "jquery": "3.3.x"
  },
  "devDependencies": {
    "angular-mocks": "1.7.x",
    "cpx": "^1.5.0",
    "http-server": "^0.11.1",
    "jasmine-core": "^3.3.0",
    "karma": "^3.1.1",
    "karma-chrome-launcher": "^2.2.0",
    "karma-firefox-launcher": "^1.1.0",
    "karma-jasmine": "^1.1.2",
    "protractor": "^5.4.1"
  },
  "scripts": {
    "postinstall": "npm run copy-libs",
    "update-deps": "npm update",
    "postupdate-deps": "npm run copy-libs",
    "copy-libs": "cpx \"node_modules/{angular,angular-*,bootstrap/dist,jquery/dist}/**/*\" app/lib -C",
    "prestart": "npm install",
    "start": "http-server ./app -a localhost -p 8000 -c-1",
    "pretest": "npm install",
    "test": "karma start karma.conf.js",
    "test-single-run": "npm test -- --single-run",
    "preupdate-webdriver": "npm install",
    "update-webdriver": "webdriver-manager update",
    "preprotractor": "npm run update-webdriver",
    "protractor": "protractor e2e-tests/protractor.conf.js"
  }
}

app.js

var app = angular.module('app', []);

app.baseUrl = 'http://localhost:8080/';

app.config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('//');
    $interpolateProvider.endSymbol('//');
});

export {app};

karma.conf.js

karma.conf.js

//jshint strict: false
// there are more things than needed, could clean up. Same in package.json
module.exports = function(config) {
    config.set({

        basePath: './app',

        files: [
            'lib/angular/angular.js',
            'lib/angular-animate/angular-animate.js',
            'lib/angular-resource/angular-resource.js',
            'lib/angular-route/angular-route.js',
            '../node_modules/angular-mocks/angular-mocks.js',
            '**/*.module.js',
            '*!(.module|.spec).js',
            '!(lib)/**/*!(.module|.spec).js',
            '**/*.spec.js',
            '../public/*.js',    // works with this because gets real files probably which we test
        ],

        autoWatch: true,

        frameworks: ['jasmine'],

        browsers: ['Chrome'],

        plugins: [
            'karma-chrome-launcher',
            'karma-jasmine'
        ]

    });
};

RecordsController.js

RecordsController.js

/*var app = angular.module('app', []);

app.baseUrl = 'http://localhost:8080/';

app.config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('//');
    $interpolateProvider.endSymbol('//');
});*/

import {app} from './app.js';

app.controller('RecordsController', ['$scope', '$http', function($scope, $http) {

    $scope.submit = function () {
        console.log($scope);
        $http.post( app.baseUrl + 'save', {name: $scope.name, price: $scope.price})
            .then(function (response) {
                $scope.records.push(response.data)
            });
    }

    $http.get(app.baseUrl + 'list')
        .then(function(response) {
            $scope.records = response.data;
        });


    $scope.grade = function(price) {
        if (price > 100) {
            return 'big';
        } else if (price > 50) {
            return 'medium';
        } else {
            return 'small';
        }
    };
}]);

//export {app};

应用程序正常运行.如果我没有app.js文件,但在与RecordsController.js相同的文件中定义app-单元测试有效.但是,当我将代码移至app.js时-测试停止工作.输出为:

Application works. If I do not have app.js file but define app in same file as RecordsController.js - unit test works. But when I moved code to app.js - test stops working. Here is output:

npm test -- --single-run

> angular-phonecat@0.0.0 pretest /home/darius/Private/Projects/learning/symfony_angular_docker
> npm install


> angular-phonecat@0.0.0 postinstall /home/darius/Private/Projects/learning/symfony_angular_docker
> npm run copy-libs


> angular-phonecat@0.0.0 copy-libs /home/darius/Private/Projects/learning/symfony_angular_docker
> cpx "node_modules/{angular,angular-*,bootstrap/dist,jquery/dist}/**/*" app/lib -C

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

audited 534 packages in 2.942s

8 packages are looking for funding
  run `npm fund` for details

found 10 vulnerabilities (6 low, 3 moderate, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

> angular-phonecat@0.0.0 test /home/darius/Private/Projects/learning/symfony_angular_docker
> karma start karma.conf.js "--single-run"

27 12 2020 07:58:51.305:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.module.js" does not match any file.
27 12 2020 07:58:51.307:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/*!(.module|.spec).js" does not match any file.
27 12 2020 07:58:51.313:WARN [watcher]: All files matched by "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.spec.js" were excluded or matched by prior matchers.
27 12 2020 07:58:51.325:INFO [karma-server]: Karma v3.1.4 server started at http://0.0.0.0:9876/
27 12 2020 07:58:51.326:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
27 12 2020 07:58:51.329:INFO [launcher]: Starting browser Chrome
27 12 2020 07:58:51.773:INFO [Chrome 87.0.4280 (Linux 0.0.0)]: Connected on socket M3VJxSZLyXP8VAmmAAAA with id 36635738
Chrome 87.0.4280 (Linux 0.0.0) ERROR: 'DEPRECATION:', 'Setting specFilter directly on Env is deprecated and will be removed in a future version of Jasmine, please use the specFilter option in `configure`'

Chrome 87.0.4280 (Linux 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\nSyntaxError: Cannot use import statement outside a module\nSyntaxError: Cannot use import statement outside a module\nSyntaxError: Unexpected token 'export'",
    "str": "An error was thrown in afterAll\nSyntaxError: Cannot use import statement outside a module\nSyntaxError: Cannot use import statement outside a module\nSyntaxError: Unexpected token 'export'"
  }
Chrome 87.0.4280 (Linux 0.0.0): Executed 0 of 0 ERROR (0.002 secs / 0 secs)
npm ERR! Test failed.  See above for more details.
 

或者您可以推荐一些教程,其中有导入文件的单元测试示例?

Or can you recommend tutorial where there is example of unit test where files are imported?

更新

karma.conf.js后@ tmhao2005答案:

karma.conf.js afeter @tmhao2005 answer:

//jshint strict: false
// there are more things than needed, could clean up. Same in package.json
module.exports = function(config) {
    config.set({

        basePath: './app',

        files: [
            'lib/angular/angular.js',
            'lib/angular-animate/angular-animate.js',
            'lib/angular-resource/angular-resource.js',
            'lib/angular-route/angular-route.js',
            '../node_modules/angular-mocks/angular-mocks.js',
            '**/*.module.js',
            '*!(.module|.spec).js',
            '!(lib)/**/*!(.module|.spec).js',
            '**/*.spec.js',
            '../public/*.js',    // works with this because gets real files probably which we test
        ],

        autoWatch: true,

        frameworks: ['jasmine'],

        browsers: ['Chrome'],

        plugins: [
            'karma-chrome-launcher',
            'karma-jasmine',
            'karma-webpack',
        ],

        preprocessors: {
            // process your `esmodule` syntax of your files
            '../public/*.js': ['webpack'],
            '**/*.spec.js': ['webpack']
        },
        webpack: {
            // karma watches the test entry points
            // (you don't need to specify the entry option)
            // webpack watches dependencies
            // webpack configuration
        },


    });
};

现在得到

npm test -- --single-run

> angular-phonecat@0.0.0 pretest /home/darius/Private/Projects/learning/symfony_angular_docker
> npm install


> angular-phonecat@0.0.0 postinstall /home/darius/Private/Projects/learning/symfony_angular_docker
> npm run copy-libs


> angular-phonecat@0.0.0 copy-libs /home/darius/Private/Projects/learning/symfony_angular_docker
> cpx "node_modules/{angular,angular-*,bootstrap/dist,jquery/dist}/**/*" app/lib -C

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/watchpack/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

audited 786 packages in 3.663s

11 packages are looking for funding
  run `npm fund` for details

found 10 vulnerabilities (6 low, 3 moderate, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

> angular-phonecat@0.0.0 test /home/darius/Private/Projects/learning/symfony_angular_docker
> karma start karma.conf.js "--single-run"

30 12 2020 17:50:53.375:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.module.js" does not match any file.
30 12 2020 17:50:53.377:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/*!(.module|.spec).js" does not match any file.
30 12 2020 17:50:53.384:WARN [watcher]: All files matched by "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.spec.js" were excluded or matched by prior matchers.
⚠ 「wdm」: Hash: d4e94cf661365475ea55
Version: webpack 4.41.1
Time: 57ms
Built at: 2020-12-30 17:50:53

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
ℹ 「wdm」: Compiled with warnings.
30 12 2020 17:50:53.408:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.module.js" does not match any file.
30 12 2020 17:50:53.409:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/*!(.module|.spec).js" does not match any file.
30 12 2020 17:50:53.417:WARN [watcher]: All files matched by "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.spec.js" were excluded or matched by prior matchers.
ℹ 「wdm」: Compiling...
⚠ 「wdm」: Hash: 4b332cf791759062b309
Version: webpack 4.41.1
Time: 18ms
Built at: 2020-12-30 17:50:53
                              Asset      Size  Chunks             Chunk Names
     ../public/RecordsController.js  1.48 KiB    1, 2  [emitted]  ../public/RecordsController
                   ../public/app.js  1.11 KiB       2  [emitted]  ../public/app
Tests/RecordsControllerTest.spec.js  1.45 KiB    0, 2  [emitted]  Tests/RecordsControllerTest.spec
Entrypoint Tests/RecordsControllerTest.spec = Tests/RecordsControllerTest.spec.js
Entrypoint ../public/app = ../public/app.js
Entrypoint ../public/RecordsController = ../public/RecordsController.js
[0] ./public/app.js 227 bytes {0} {1} {2} [built]
[1] ./app/Tests/RecordsControllerTest.spec.js 952 bytes {0} [built]
[2] ./public/RecordsController.js 957 bytes {1} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
ℹ 「wdm」: Compiled with warnings.
30 12 2020 17:50:53.568:INFO [karma-server]: Karma v3.1.4 server started at http://0.0.0.0:9876/
30 12 2020 17:50:53.568:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
30 12 2020 17:50:53.573:INFO [launcher]: Starting browser Chrome
30 12 2020 17:50:53.969:INFO [Chrome 87.0.4280 (Linux 0.0.0)]: Connected on socket xExD5D27bFhOOfMsAAAA with id 98015757
Chrome 87.0.4280 (Linux 0.0.0) ERROR: 'DEPRECATION:', 'Setting specFilter directly on Env is deprecated and will be removed in a future version of Jasmine, please use the specFilter option in `configure`'

Chrome 87.0.4280 (Linux 0.0.0) RecordsController $scope.grade sets the strength FAILED
    Error: [$injector:modulerr] Failed to instantiate module app due to:
    Error: [$injector:unpr] Unknown provider: e
    
    https://errors.angularjs.org/1.7.9/$injector/modulerr?p0=app&p1=Error%3A%20%5B%24injector%3Aunpr%5D%20Unknown%20provider%3A%20e%0Ahttps%3A%2F%2Ferrors.angularjs.org%2F1.7.9%2F%24injector%2Funpr%3Fp0%3De%0A%20%20%20%20at%20http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A138%3A12%0A%20%20%20%20at%20http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A4926%3A19%0A%20%20%20%20at%20getService%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A5086%3A32)%0A%20%20%20%20at%20injectionArgs%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A5111%3A58)%0A%20%20%20%20at%20Object.invoke%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A5135%3A18)%0A%20%20%20%20at%20runInvokeQueue%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A5032%3A35)%0A%20%20%20%20at%20http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A5042%3A11%0A%20%20%20%20at%20forEach%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A387%3A20)%0A%20%20%20%20at%20loadModules%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A5022%3A5)%0A%20%20%20%20at%20Object.createInjector%20%5Bas%20injector%5D%20(http%3A%2F%2Flocalhost%3A9876%2Fbase%2Flib%2Fangular%2Fangular.js%3F59efdd7db87c914e8c987ccc770455b4feb59f8f%3A4939%3A19)
        at <Jasmine>
        at lib/angular/angular.js:138:12
        at lib/angular/angular.js:5062:15
        at forEach (lib/angular/angular.js:387:20)
        at loadModules (lib/angular/angular.js:5022:5)
        at Object.createInjector [as injector] (lib/angular/angular.js:4939:19)
        at UserContext.WorkFn (/home/darius/Private/Projects/learning/symfony_angular_docker/node_modules/angular-mocks/angular-mocks.js:3449:52)
        at <Jasmine>
    TypeError: Cannot read property '$new' of undefined
        at UserContext.<anonymous> (Tests/RecordsControllerTest.spec.js:1:1385)
        at <Jasmine>
Chrome 87.0.4280 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.002 secs / 0.008 secs)
npm ERR! Test failed.  See above for more details.

更新2

将$ interpolateProvider添加为依赖项,现在为app.js:

Added $interpolateProvider as dependency, app.js now:

var app = angular.module('app', []);

app.baseUrl = 'http://localhost:8080/';

app.config(['$interpolateProvider', function($interpolateProvider) {
    $interpolateProvider.startSymbol('//');
    $interpolateProvider.endSymbol('//');
}]);

export {app};

现在添加了开发模式karma.conf.js:

Added development mode, karma.conf.js now:

//jshint strict: false
// there are more things than needed, could clean up. Same in package.json
module.exports = function(config) {
    config.set({

        basePath: './app',

        files: [
            'lib/angular/angular.js',
            'lib/angular-animate/angular-animate.js',
            'lib/angular-resource/angular-resource.js',
            'lib/angular-route/angular-route.js',
            '../node_modules/angular-mocks/angular-mocks.js',
            '**/*.module.js',
            '*!(.module|.spec).js',
            '!(lib)/**/*!(.module|.spec).js',
            '**/*.spec.js',
            '../public/*.js',    // works with this because gets real files probably which we test
        ],

        autoWatch: true,

        frameworks: ['jasmine'],

        browsers: ['Chrome'],

        plugins: [
            'karma-chrome-launcher',
            'karma-jasmine',
            'karma-webpack',
        ],

        preprocessors: {
            // process your `esmodule` syntax of your files
            '../public/*.js': ['webpack'],
            '**/*.spec.js': ['webpack']
        },
        webpack: {
            // karma watches the test entry points
            // (you don't need to specify the entry option)
            // webpack watches dependencies
            // webpack configuration.
            // dev mode for tests to work
            "mode": "development",
        },
    });
};

现在出现错误:

darius@darius-Vostro-5481:~/Private/Projects/learning/symfony_angular_docker$ npm test -- --single-run

> angular-phonecat@0.0.0 pretest /home/darius/Private/Projects/learning/symfony_angular_docker
> npm install


> angular-phonecat@0.0.0 postinstall /home/darius/Private/Projects/learning/symfony_angular_docker
> npm run copy-libs


> angular-phonecat@0.0.0 copy-libs /home/darius/Private/Projects/learning/symfony_angular_docker
> cpx "node_modules/{angular,angular-*,bootstrap/dist,jquery/dist}/**/*" app/lib -C

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.1.3 (node_modules/watchpack/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

audited 786 packages in 3.714s

11 packages are looking for funding
  run `npm fund` for details

found 10 vulnerabilities (6 low, 3 moderate, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

> angular-phonecat@0.0.0 test /home/darius/Private/Projects/learning/symfony_angular_docker
> karma start karma.conf.js "--single-run"

05 01 2021 17:03:25.368:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.module.js" does not match any file.
05 01 2021 17:03:25.370:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/*!(.module|.spec).js" does not match any file.
05 01 2021 17:03:25.376:WARN [watcher]: All files matched by "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.spec.js" were excluded or matched by prior matchers.
ℹ 「wdm」: Hash: 3879665b411e2fff46cc
Version: webpack 4.41.1
Time: 53ms
Built at: 2021-01-05 17:03:25
ℹ 「wdm」: Compiled successfully.
05 01 2021 17:03:25.396:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.module.js" does not match any file.
05 01 2021 17:03:25.397:WARN [watcher]: Pattern "/home/darius/Private/Projects/learning/symfony_angular_docker/app/*!(.module|.spec).js" does not match any file.
05 01 2021 17:03:25.402:WARN [watcher]: All files matched by "/home/darius/Private/Projects/learning/symfony_angular_docker/app/**/*.spec.js" were excluded or matched by prior matchers.
ℹ 「wdm」: Compiling...
ℹ 「wdm」: Hash: bfe70362116b7e4fdf82
Version: webpack 4.41.1
Time: 18ms
Built at: 2021-01-05 17:03:25
                              Asset      Size                            Chunks             Chunk Names
     ../public/RecordsController.js  5.83 KiB       ../public/RecordsController  [emitted]  ../public/RecordsController
                   ../public/app.js  4.23 KiB                     ../public/app  [emitted]  ../public/app
Tests/RecordsControllerTest.spec.js  5.77 KiB  Tests/RecordsControllerTest.spec  [emitted]  Tests/RecordsControllerTest.spec
Entrypoint ../public/app = ../public/app.js
Entrypoint Tests/RecordsControllerTest.spec = Tests/RecordsControllerTest.spec.js
Entrypoint ../public/RecordsController = ../public/RecordsController.js
[./app/Tests/RecordsControllerTest.spec.js] 954 bytes {Tests/RecordsControllerTest.spec} [built]
[./public/RecordsController.js] 958 bytes {../public/RecordsController} [built]
[./public/app.js] 253 bytes {../public/app} {Tests/RecordsControllerTest.spec} {../public/RecordsController} [built]
ℹ 「wdm」: Compiled successfully.
05 01 2021 17:03:25.502:INFO [karma-server]: Karma v3.1.4 server started at http://0.0.0.0:9876/
05 01 2021 17:03:25.503:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
05 01 2021 17:03:25.507:INFO [launcher]: Starting browser Chrome
05 01 2021 17:03:25.963:INFO [Chrome 87.0.4280 (Linux 0.0.0)]: Connected on socket t4Hc0-IijbJd_27rAAAA with id 24424610
Chrome 87.0.4280 (Linux 0.0.0) ERROR: 'DEPRECATION:', 'Setting specFilter directly on Env is deprecated and will be removed in a future version of Jasmine, please use the specFilter option in `configure`'

Chrome 87.0.4280 (Linux 0.0.0) RecordsController $scope.grade sets the strength FAILED
    Error: [$controller:ctrlreg] The controller with the name 'RecordsController' is not registered.
    https://errors.angularjs.org/1.7.9/$controller/ctrlreg?p0=RecordsController
        at lib/angular/angular.js:138:12
        at $controller (lib/angular/angular.js:11680:17)
        at /home/darius/Private/Projects/learning/symfony_angular_docker/node_modules/angular-mocks/angular-mocks.js:2555:14
        at UserContext.eval (webpack:///./app/Tests/RecordsControllerTest.spec.js?:22:34)
        at <Jasmine>
Chrome 87.0.4280 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.005 secs / 0.01 secs)
npm ERR! Test failed.  See above for more details.

更新3:

我在想-也许它没有看到控制器,因为它没有控制器就导入了app.js?并且控制器在另一个文件中分配给该应用程序.但是测试只是看不到另一个文件.也许我需要从RecordsController.js文件中以某种方式导出控制器?并将其导入测试中吗?

I am thinking - maybe it does not see the controller because it imports app.js without controller? And controller is assigned in another file to the app. But test just does not see that another file. Maybe I need to export somehow controller from RecordsController.js file? And import it in the test?

推荐答案

在tmhao2005答案的帮助下,经过了这么长时间,终于找到了可行的解决方案:

After so much time finnaly with the help of tmhao2005 answer found a working solution:

app.js

var app = angular.module('app', []);

app.baseUrl = 'http://localhost:8080/';

app.config(['$interpolateProvider', function($interpolateProvider) {
    $interpolateProvider.startSymbol('//');
    $interpolateProvider.endSymbol('//');
}]);

export {app};

single_page.html.twig

single_page.html.twig

<html>

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.9/angular.js"></script>
    {#    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>#}

    <script type="module" src="RecordsController.js"></script>
</head>

<body ng-app="app" >
    <div class="container">
        <div ng-controller="RecordsController">
            <h1>Records controller</h1> <br>

            <div class="row col-md-4">
                <form>
                    <div class="form-group">
                        <label>Name</label>
                        <input type="text" class="form-control" ng-model="name" id="name">
                    </div>
                    <div class="form-group">
                        <label>Price</label>
                        <input type="number" class="form-control" ng-model="price" id="price">
                    </div>
                    <button type="submit" class="btn btn-primary" ng-click="submit()">Submit</button>
                </form>
            </div>


            <table class="table table-bordered">
                <tr>

                    <th>Id</th>
                    <th>Name</th>
                    <th>Price</th>
                    <th>Size</th>
                </tr>
                <tr ng-repeat="(key, record) in records">
                    <td>// record.id //</td>
                    <td>// record.name //</td>
                    <td>// record.price //</td>
                    <td>// grade(record.price) //</td>
                </tr>
            </table>

            <a-great-eye></a-great-eye>
        </div> <!-- end records controller -->
    </div>

</body>
</html>

RecordsControllerTest.spec.js

RecordsControllerTest.spec.js

import {RecordsController} from '../../public/RecordsController.js';

describe('RecordsController', function() {
    var $controller, $rootScope, $http;

    beforeEach(inject(function(_$controller_, _$rootScope_, _$http_){
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $controller = _$controller_;
        $rootScope = _$rootScope_;
        $http = _$http_;
    }));

    describe('$scope.grade', function() {
        it('sets the strength', function() {
            var $scope = $rootScope.$new();

            var controller = new RecordsController($scope, $http);

            let grade = $scope.grade(1);
            expect(grade).toEqual('small');
        });
    });
});

package.json

package.json

{
  "name": "angular-phonecat",
  "private": true,
  "version": "0.0.0",
  "description": "A tutorial application for AngularJS",
  "repository": "https://github.com/angular/angular-phonecat",
  "license": "MIT",
  "dependencies": {
    "angular": "1.7.x",
    "angular-animate": "1.7.x",
    "angular-resource": "1.7.x",
    "angular-route": "1.7.x",
    "bootstrap": "3.3.x",
    "jquery": "3.3.x"
  },
  "devDependencies": {
    "angular-mocks": "1.7.x",
    "cpx": "^1.5.0",
    "http-server": "^0.11.1",
    "jasmine-core": "^3.3.0",
    "karma": "^3.1.1",
    "karma-chrome-launcher": "^2.2.0",
    "karma-firefox-launcher": "^1.1.0",
    "karma-jasmine": "^1.1.2",
    "karma-webpack": "^4.0.2",
    "protractor": "^5.4.1",
    "webpack": "^4.41.1"
  },
  "scripts": {
    "postinstall": "npm run copy-libs",
    "update-deps": "npm update",
    "postupdate-deps": "npm run copy-libs",
    "copy-libs": "cpx \"node_modules/{angular,angular-*,bootstrap/dist,jquery/dist}/**/*\" app/lib -C",
    "prestart": "npm install",
    "start": "http-server ./app -a localhost -p 8000 -c-1",
    "pretest": "npm install",
    "test": "karma start karma.conf.js",
    "test-single-run": "npm test -- --single-run",
    "preupdate-webdriver": "npm install",
    "update-webdriver": "webdriver-manager update",
    "preprotractor": "npm run update-webdriver",
    "protractor": "protractor e2e-tests/protractor.conf.js"
  }
}

RecordsController.js

RecordsController.js

import {app} from './app.js';

function RecordsController($scope, $http)
{
    $scope.submit = function () {
        console.log($scope);
        $http.post( app.baseUrl + 'save', {name: $scope.name, price: $scope.price})
            .then(function (response) {
                $scope.records.push(response.data)
            });
    }

    $http.get(app.baseUrl + 'list')
        .then(function(response) {
            $scope.records = response.data;
        });


    $scope.grade = function(price) {
        if (price > 100) {
            return 'big';
        } else if (price > 50) {
            return 'medium';
        } else {
            return 'small';
        }
    };
}

app.controller('RecordsController', RecordsController);

export {RecordsController};

karma.conf.js

karma.conf.js

//jshint strict: false
// there are more things than needed, could clean up. Same in package.json
module.exports = function(config) {
    config.set({

        basePath: './app',

        files: [
            'lib/angular/angular.js',
            'lib/angular-animate/angular-animate.js',
            'lib/angular-resource/angular-resource.js',
            'lib/angular-route/angular-route.js',
            '../node_modules/angular-mocks/angular-mocks.js',
            '**/*.module.js',
            '*!(.module|.spec).js',
            '!(lib)/**/*!(.module|.spec).js',
            '**/*.spec.js',
            '../public/*.js',    // works with this because gets real files probably which we test
        ],

        autoWatch: true,

        frameworks: ['jasmine'],

        browsers: ['Chrome'],

        plugins: [
            'karma-chrome-launcher',
            'karma-jasmine',
            'karma-webpack',
        ],

        preprocessors: {
            // process your `esmodule` syntax of your files
            '../public/*.js': ['webpack'],
            '**/*.spec.js': ['webpack']
        },
        webpack: {
            // karma watches the test entry points
            // (you don't need to specify the entry option)
            // webpack watches dependencies
            // webpack configuration.
            // dev mode for tests to work
            "mode": "development",
        },
    });
};

所以最后一个问题是测试正在导入app.js,但是在app.js文件中,控制器未分配给app.它被分配在不同的文件中.但是我无法对此进行测试.但是不同的解决方案是使RecordsController成为单独的函数.这样就不必模拟应用程序了.

So really last problem was that test was importing app.js but in app.js file the controller was not assingned to app. It was assigned in different file. But I was not able to make test know about this. But different solution was to make RecordsController as seperate function. Then there is no need to even mock app.

我不确定是否

app.controller('RecordsController', RecordsController);

从体系结构的角度来看,

很好地包含在RecordsController文件中.

is good to have in RecordsController file, from architecture point of view.

这篇关于如何解决“无法在模块外部使用import语句"用angularjs运行业力单元测试时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆