Jasmine beforeEach不等待完成回调

时间:2017-10-06 11:04:12

标签: javascript asynchronous webpack jasmine karma-runner

我遇到了Jasmine(+ Karma + Webpack)的问题

我将测试缩小到beforeEach语句,而不是在运行done()块之前等待it回调执行。

编辑: Navjot Ahuja指出jasmine-node与setTimeout中的beforeEach存在问题,因此我将其更改为使用承诺,与他的建议略有不同(作为他的作品,但这个例子没有)

以下是我发现的一些奇怪的事情:

  • 测试似乎打印了两次。我已经看过几个关于这个的线程,所以它可能只是使用spec插件(或`点)
    • 我在测试运行器浏览器窗口中看到一些茉莉花错误,我将在下面发布。我怀疑这可能是问题的原因,但我不知道如何解决。
    • 如果我改为使用beforeAll它可以工作(但这不是一个选项)

这是测试:

describe('Test', function () {
    let flag = false;

    describe('simple test -', function () {
        beforeEach(function (done) {
            console.log('SETTING TIMEOUT');

            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    flag = true;
                    done();
                }
            };
            xhttp.open('GET', 'https://api.github.com/zen', true);
            xhttp.send();
        });
        it('should wait for done and set flag correctly', function () {
            console.log('INSIDE IT STATEMENT');
            expect(flag).toBe(true);
        });
    });
});

这是karma.conf.js

// Karma configuration
const webpackTestConfig = require('./build/tests.webpack.config.js');

module.exports = function (config) {
    const webpackConfig = webpackTestConfig;

    config.set({
        client: {
            args: [
                `--ver=${config.ver}`,
                `--region=${config.region}`,
                `--env=${config.env}`
            ],
            captureConsole: true
        },

        basePath: '',
        frameworks: ['jasmine'],
        files: [
            'tests/integration/integrationTests.js'
        ],

        reporters: ['spec', 'junit'],
        junitReporter: {
            useBrowserName: false,
            outputFile: 'reports/js/unit-components/results/ITESTS-junit.xml'
        },

        coverageReporter: {
            reporters: [
                {type: 'text-summary', dir: 'reports/js/unit-components/coverage/text-summary/', subdir: '.'},
                {type: 'lcov', dir: 'reports/js/unit-components/coverage/lcov/', subdir: '.'},
                {type: 'html', dir: 'reports/js/unit-components/coverage/html', subdir: '.'},
                {type: 'cobertura', dir: 'reports/js/unit-components/coverage/cobertura', subdir: '.'}
            ]
        },

        preprocessors: {
            'tests/integration/integrationTests.js': ['webpack']
        },
        webpack: webpackConfig,
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        browsers: ['Chrome'],
        captureTimeout: 60000,
        browserNoActivityTimeout: 600000,
        singleRun: false
    });
};

这是test.webpack.config.js

/*global __dirname*/
const webpackConfigBase = require('./webpack.config.js');
const path = require('path');
const _ = require('underscore');
const rootDir = path.resolve(__dirname, '..');

module.exports = () => {
    const config = webpackConfigBase();

    _.extend(config.resolve.alias, {
        'integrationTests': path.join(rootDir, 'tests/integration'),
        'testUtils': path.join(rootDir, 'tests/util'),
        'testFixtures': path.join(rootDir, 'tests/fixture')
    });

    return config;
};

这是引用的基本webpack配置:

/* globals __dirname */
const path = require('path');
const rootDir = path.resolve(__dirname, '..');

function matchModule(resource, moduleName) {
    return resource && resource.indexOf(moduleName) >= 0;
}

module.exports = () => ({
    context: path.join(rootDir, 'www/latest/'),
    entry: './app/api.js',
    resolve: {
        modules: [
            path.join(rootDir, 'www/latest/app'),
            path.join(rootDir, 'node_modules')
        ],
        alias: {
            'vendor': path.join(rootDir, 'www/latest/vendor')
            // other paths here but removed
        }
    },
    output: {
        path: path.join(rootDir, 'www/latest/dist/'),
        publicPath: 'CENSOREDPATH',
        filename: 'api.js',
        devtoolModuleFilenameTemplate: 'applicationname://[resource-path]',
        devtoolFallbackModuleFilenameTemplate: 'applicationname://[resource-path]?[hash]'
    },
    module: {
        rules: [
            {
                enforce: 'pre',
                test: /\.js$/,
                loader: 'eslint-loader'
            },
            {
                test: /\.js$/,
                exclude: function (resource) {
                    const es6Vendors = [
                        'vendor/censored/src',
                        'vendor/babel'
                    ];
                    const isNodeModule = matchModule(resource, 'node_modules');
                    const isVendor = matchModule(resource, 'vendor');
                    const isEs6Vendor = (es6Vendors.filter(vendor => matchModule(resource, vendor)).length >= 1);

                    if (isNodeModule || (isVendor && !isEs6Vendor)) {
                        return true;
                    }

                    return false;
                },
                loader: 'babel-loader'
            }
        ]
    },
    externals: {
        'react/addons': true,
        'react/lib/ExecutionEnvironment': true,
        'react/lib/ReactContext': true
    },
    node: {
        setImmediate: false,
        clearImmediate: false
    }
});

=============================================== ==========================

这是控制台的输出:

Version: webpack 3.6.0
Time: 39ms
webpack: Compiled successfully.
    webpack: Compiling...
06 10 2017 07:30:01.789:WARN [karma]: No captured browser, open http://localhost:9876/
    Hash: 020b93689ec1147a0c3b
Version: webpack 3.6.0
Time: 70ms
Asset     Size  Chunks             Chunk Names
tests/integration/integrationTests.js  3.96 kB       0  [emitted]  tests/integration/integrationTests.js
    [0] ./tests/integration/integrationTests.js 238 bytes {0} [built]
    [1] ./tests/integration models\/item.spec.js$ 192 bytes {0} [built]
    [2] ./tests/integration/specs/models/item.spec.js 612 bytes {0} [optional] [built]
webpack: Compiled successfully.
06 10 2017 07:30:01.799:INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/
    06 10 2017 07:30:01.800:INFO [launcher]: Launching browser Chrome with unlimited concurrency
06 10 2017 07:30:01.812:INFO [launcher]: Starting browser Chrome
06 10 2017 07:30:02.238:INFO [Chrome 61.0.3163 (Linux 0.0.0)]: Connected on socket mL2CqoCdzxFggtuIAAAA with id 72267743
Chrome 61.0.3163 (Linux 0.0.0) LOG LOG: '=================', './specs/models/item.spec.js', '================='
LOG LOG: 'SETTING TIMEOUT'
LOG LOG: 'INSIDE IT STATEMENT'

Test
simple test -
Test
simple test -
✗ should wait for done and set flag correctly
Expected false to be true.
    at UserContext.<anonymous> (tests/integration/integrationTests.js:121:30)

✗ should wait for done and set flag correctly
Expected false to be true.
    at UserContext.<anonymous> (tests/integration/integrationTests.js:121:30)


Chrome 61.0.3163 (Linux 0.0.0): Executed 2 of 1 (2 FAILED) ERROR (0.007 secs / 0.003 secs)

上述控制台错误的显着错误是:

  1. Uncaught TypeError: Cannot read property 'spies' of undefined
  2. Uncaught Error: Tried to complete the wrong suite
  3. 完整输出:

    ================= ./specs/models/item.spec.js =================
    integrationTests.js:120 asdfasdf
    
    debug.js:15 FAILED Test simple test - Test simple test - should wait for done and set flag correctly
    
    debug.js:15 FAILED Test simple test - should wait for done and set flag correctly
    
    2debug.js:6 Skipped 0 tests
    
    integrationTests.js:120 asdfasdf
    debug.js:21 Uncaught Expected false to be true.
        at UserContext.<anonymous> (http://karma.vg.censored.com/base/tests/integration/integrationTests.js:121:26)
    
        (anonymous) @ debug.js:21
    setTimeout (async)
    (anonymous) @ debug.js:20
    window.__karma__.result @ debug.js:23
    KarmaReporter.specDone @ adapter.js:243
    dispatch @ jasmine.js:4366
    (anonymous) @ jasmine.js:4337
    specResultCallback @ jasmine.js:1175
    complete @ jasmine.js:530
    (anonymous) @ jasmine.js:4231
    channel.port1.onmessage @ jasmine.js:1774
    debug.js:21 Uncaught Expected false to be true.
        at UserContext.<anonymous> (http://karma.vg.censored.com/base/tests/integration/integrationTests.js:121:26)
        (anonymous) @ debug.js:21
    setTimeout (async)
    (anonymous) @ debug.js:20
    window.__karma__.result @ debug.js:23
    KarmaReporter.specDone @ adapter.js:243
    dispatch @ jasmine.js:4366
    (anonymous) @ jasmine.js:4337
    specResultCallback @ jasmine.js:1175
    complete @ jasmine.js:530
    (anonymous) @ jasmine.js:4231
    channel.port1.onmessage @ jasmine.js:1774
    
    
    jasmine.js:1024 Uncaught TypeError: Cannot read property 'spies' of undefined
    at currentSpies (jasmine.js:1024)
    at SpyRegistry.clearSpies (jasmine.js:4848)
    at clearResourcesForRunnable (jasmine.js:818)
    at Spec.specResultCallback [as resultCallback] (jasmine.js:1173)
    at QueueRunner.complete [as onComplete] (jasmine.js:530)
    at jasmine.js:4231
    at MessagePort.channel.port1.onmessage (jasmine.js:1774)
    currentSpies @ jasmine.js:1024
    SpyRegistry.clearSpies @ jasmine.js:4848
    clearResourcesForRunnable @ jasmine.js:818
    specResultCallback @ jasmine.js:1173
    complete @ jasmine.js:530
    (anonymous) @ jasmine.js:4231
    channel.port1.onmessage @ jasmine.js:1774
    
    
    jasmine.js:1024 Uncaught TypeError: Cannot read property 'spies' of undefined
    at currentSpies (jasmine.js:1024)
    at SpyRegistry.clearSpies (jasmine.js:4848)
    at clearResourcesForRunnable (jasmine.js:818)
    at nodeComplete (jasmine.js:955)
    at QueueRunner.onComplete (jasmine.js:5327)
    at jasmine.js:4231
    at MessagePort.channel.port1.onmessage (jasmine.js:1774)
    currentSpies @ jasmine.js:1024
    SpyRegistry.clearSpies @ jasmine.js:4848
    clearResourcesForRunnable @ jasmine.js:818
    nodeComplete @ jasmine.js:955
    onComplete @ jasmine.js:5327
    (anonymous) @ jasmine.js:4231
    channel.port1.onmessage @ jasmine.js:1774
    
    
    jasmine.js:951 Uncaught Error: Tried to complete the wrong suite
    at nodeComplete (jasmine.js:951)
    at QueueRunner.onComplete (jasmine.js:5327)
    at jasmine.js:4231
    at MessagePort.channel.port1.onmessage (jasmine.js:1774)
    nodeComplete @ jasmine.js:951
    onComplete @ jasmine.js:5327
    (anonymous) @ jasmine.js:4231
    channel.port1.onmessage @ jasmine.js:1774
    
    
    jasmine.js:1024 Uncaught TypeError: Cannot read property 'spies' of undefined
    at currentSpies (jasmine.js:1024)
    at SpyRegistry.clearSpies (jasmine.js:4848)
    at clearResourcesForRunnable (jasmine.js:818)
    at QueueRunner.onComplete (jasmine.js:984)
    at jasmine.js:4231
    at MessagePort.channel.port1.onmessage (jasmine.js:1774)
    currentSpies @ jasmine.js:1024
    SpyRegistry.clearSpies @ jasmine.js:4848
    clearResourcesForRunnable @ jasmine.js:818
    (anonymous) @ jasmine.js:984
    (anonymous) @ jasmine.js:4231
    channel.port1.onmessage @ jasmine.js:1774
    
    
    jasmine.js:2373 Uncaught Uncaught TypeError: Cannot read property 'spies' of undefined
    

    我现在花了很多时间在这上面并且没有任何线索,有人可以提出建议吗?

1 个答案:

答案 0 :(得分:0)

我想现在jasmine-node不支持超时(问题:https://github.com/mhevery/jasmine-node/issues/344

您可以使用承诺。像这样:

&#13;
&#13;
describe('Test', function() {
  let flag = false;
  let beforeEachPromise;
  describe('simple test -', function() {
    beforeEach(function(done) {
      console.log('SETTING TIMEOUT');
      beforeEachPromise = new Promise(function(resolve, reject) {
        setTimeout(function() {
          console.log('TIMEOUT CALLBACK TRIGGERED');
          flag = true;
          done();
        }, 2000);
      })
    });
    it('should wait for done and set flag correctly', function() {
      beforeEachPromise.then(function() {
        expect(flag).toBe(true);
      })
    });
  });
});
&#13;
&#13;
&#13;