Why am I getting this Angular-Mock error and Mocha

2019-08-11 11:19发布

问题:

I'm getting the exact error as found here: (window.beforeEach || window.setup) is not a function. However the fix did not work, the author of the tutorial series here even mentioned the same fix.

Here is the Tuts+ author's fix:

Which is simply to place the angular-mock script tag after the Mochai and Chai scripts. Which I did so below:

test/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Mocha Spec Runner</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="icon" href="../app/favicon.ico">
    <link rel="apple-touch-icon" href="../app/assets/imgs/apple-touch-icon.png">
    <link href="bower_components/mocha/mocha.css" rel="stylesheet">
</head>

<body>

    <div id="mocha"></div>

    <script src="../bower_components/angular/angular.js"></script>
    <script src="../bower_components/mocha/mocha.js"></script>
    <script src="../bower_components/chai/chai.js"></script>
    <!-- see Angular-mocks is here :( -->
    <script src="../bower_components/angular-mocks/angular-mocks.js"></script>

    <script>
        mocha.setup('bdd');
    </script>

    <script src="main.spec.js"></script>

    <script>
        mocha.run();
    </script>

</body>
</html>

My main.spec.js file

/**
 * @name Mocha Test Runner
 * @desc Describes and runs our dashboard tests
 */

var assert = chai.assert;
var expect = chai.expect;

// This Test is designed to fail on purpose
describe('User Login', function() {
    console.log('User Login');
    describe('Login Failed', function() {
        console.log('Login Failed');
        if ('Incorrect login should fail', function() {
            module('loginController')
            inject(function($injector) {
                apiFactory = $injector.get('ApiFactory');
            });

            expect(apiFactory).to.be.an('number');
        });
    });    
});

My Gulp tasks

gulp.task('serve', function() {
    return browserSync.init({
        notify : false,
        port   : 3333,
        server: {
            baseDir: ['app'],
            routes: {
                '/bower_components' : 'bower_components'
            }
        }
    });
});

gulp.task('serve-test', function() {
    browserSync.init({
        notify : false,
        port   : 4444,
        server: {
            baseDir: ['test', 'app'],
            routes: {
                '/bower_components' : 'bower_components'
            }
        }
    });
});

回答1:

In your index.html file, you include the angular-mocks.js script before the call to mocha.setup('bdd'). angular-mocks.js is implemented as an immediately-invoked function expression which attempts to use window.beforeEach. (https://github.com/angular/bower-angular-mocks/blob/master/angular-mocks.js#L2586)

However, mocha.js is not immediately invoked and has to be initialized with the mocha.setup function in order to add its magic to the runtime environment.

Try reversing the order of these script tags, so that mocha.js is included and initialized before angular-mocks.js.

    <script src='bower_components/mocha/mocha.js'></script>
    <script src='bower_components/chai/chai.js'></script>
    <script>
        mocha.setup('bdd');
    </script>
    <script src="bower_components/angular-mocks/angular-mocks.js"></script>