Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Angular.js单元测试“;注入();在“a”之前开火;“运行”;相位块_Javascript_Angularjs_Unit Testing_Mocha.js_Karma Runner - Fatal编程技术网

Javascript Angular.js单元测试“;注入();在“a”之前开火;“运行”;相位块

Javascript Angular.js单元测试“;注入();在“a”之前开火;“运行”;相位块,javascript,angularjs,unit-testing,mocha.js,karma-runner,Javascript,Angularjs,Unit Testing,Mocha.js,Karma Runner,我有一个场景,我正在尝试为移动设备加载HTML5音频,这只能通过用户交互(例如ontouchstart)实现。我已经在一个角度运行阶段实现了这个逻辑,以确保尽早连接它。我无法在配置阶段附加此项,因为它依赖于其他角度工厂: angular.module('MyModule') .run(['Device', 'ResourceManager', 'ExceptionFactory', function (Device, ResourceManager, ExceptionFactory)

我有一个场景,我正在尝试为移动设备加载HTML5音频,这只能通过用户交互(例如ontouchstart)实现。我已经在一个角度运行阶段实现了这个逻辑,以确保尽早连接它。我无法在配置阶段附加此项,因为它依赖于其他角度工厂:

angular.module('MyModule')
    .run(['Device', 'ResourceManager', 'ExceptionFactory', function (Device, ResourceManager, ExceptionFactory) {
        if (!Device.browser.features.webaudio) {
            var onFirstUserInteraction = function () {
                var sounds = ResourceManager.getSounds();

                if (sounds.length > 1) {
                    throw ExceptionFactory.create('Html5AudioLimitReachedException', 'Html5 Audio Devices can only load one sound resource');
                }

                if (sounds.length === 1) {
                    sounds[0].createBrowserAudioObject();
                }

                document.documentElement.removeEventListener(Device.browser.is.IE ? 'click' : 'touchstart', onFirstUserInteraction, true);
            };

            document.documentElement.addEventListener(Device.browser.is.IE ? 'click' : 'touchstart', onFirstUserInteraction, true);
        }
    }]);
我发现以下单元测试失败,因为上面的事件处理程序未及时注册:

beforeEach(function () {
    angular.module('Html5SoundLoaderApp', [])
        .run(['Device', 'ResourceManager', function (Device, ResourceManager) {
            Device.browser.features.webaudio = false;
            ResourceManager.addSound('testOne', 'test/url/testOne.mp3', {});
            ResourceManager.addSound('testTwo', 'test/url/testTwo.mp3', {});
        }]);

    module('Html5SoundLoaderApp');
});

it('should only be able to load one sound resource', inject(['ExceptionFactory', function (ExceptionFactory) {
    var spy = sinon.spy(ExceptionFactory, 'create');

    expect(function () {
        angular.mock.ui.trigger(document.documentElement, 'touchstart')
    }).to.throw();

    spy.should.have.been.calledOnce;
    spy.should.have.been.calledWith('Html5AudioLimitReachedException', 'Html5 Audio Devices can only load one sound resource');
}]));
我希望run()块在测试开始之前已经完成了执行?我的假设错了吗?如果是这样,如何最好地解决这种情况


感谢代码在我看来是异步的(因为它正在等待用户交互,一方面),所以使用
done()
回调:

beforeEach(function (done) { // <--- Add this parameter.
    angular.module('Html5SoundLoaderApp', [])
        .run(['Device', 'ResourceManager', function (Device, ResourceManager) {
            Device.browser.features.webaudio = false;
            ResourceManager.addSound('testOne', 'test/url/testOne.mp3', {});
            ResourceManager.addSound('testTwo', 'test/url/testTwo.mp3', {});
            done(); // <--- It looks to me like this is where done() should be called.
        }]);

    module('Html5SoundLoaderApp');
});

beforeach(function(done){//为什么在测试中定义模块?测试应该包含模拟和测试。
module('Html5SoundLoaderApp'))
可能会返回一个函数,您可能想调用它。您好@idursun。这与我的问题没有直接关系,但感谢您的回答。因此,如果我采用这种方法,我必须模拟代码库中的每个服务/工厂?这意味着我必须维护两批代码,因为大多数组件都是重复使用的d在整个应用程序中?除非我理解错误?谢谢@Louis!这确实是为什么测试在运行块完成之前启动的原因。但是,我注意到了上面@idursun的评论,我已经将事件侦听器重新分解为it自己的服务,我正在模拟设备和资源管理器服务。谢谢你们两个。