Javascript 如何在Jasmine测试中释放AudioContext

Javascript 如何在Jasmine测试中释放AudioContext,javascript,angularjs,unit-testing,karma-jasmine,audiocontext,Javascript,Angularjs,Unit Testing,Karma Jasmine,Audiocontext,我有一个角度服务,可以设置音频上下文。Jasmine正在为每个测试创建一个新的服务,因此在6个测试之后,所有测试都会失败并出现错误: 错误:构造“AudioContext”失败:提供的硬件上下文数(6)大于或等于最大限制(6)。 有没有一种方法可以让我在测试之间清除音频上下文?我在每一个块后都尝试了AudioPlayer.context.close(),但似乎不起作用 服务看起来有点像这样: angular.module('myApp') .service('AudioPlayer', fu

我有一个角度服务,可以设置音频上下文。Jasmine正在为每个测试创建一个新的服务,因此在6个测试之后,所有测试都会失败并出现错误:

错误:构造“AudioContext”失败:提供的硬件上下文数(6)大于或等于最大限制(6)。

有没有一种方法可以让我在测试之间清除音频上下文?我在每一个块后都尝试了
AudioPlayer.context.close()
,但似乎不起作用

服务看起来有点像这样:

angular.module('myApp')
  .service('AudioPlayer', function () {

    var self = this;

    self.context = new AudioContext();

    this.doSomething = function () {
       // doing super cool testable stuff here
    }
  })
describe('AudioPlayer', function () {
  var AudioPlayer;

  beforeEach(function () {
    inject(function ($injector) {
      AudioPlayer = $injector.get('AudioPlayer');
    });
  });

  afterEach(function () {
    AudioPlayer.context.close();
  });

  it('does cool stuff', function () {
    AudioPlayer.doSomething();    
    // unit test
  });

  it('does other cool stuff', function () {
    AudioPlayer.doSomething();    
    // unit test
  });

});
测试看起来有点像这样:

angular.module('myApp')
  .service('AudioPlayer', function () {

    var self = this;

    self.context = new AudioContext();

    this.doSomething = function () {
       // doing super cool testable stuff here
    }
  })
describe('AudioPlayer', function () {
  var AudioPlayer;

  beforeEach(function () {
    inject(function ($injector) {
      AudioPlayer = $injector.get('AudioPlayer');
    });
  });

  afterEach(function () {
    AudioPlayer.context.close();
  });

  it('does cool stuff', function () {
    AudioPlayer.doSomething();    
    // unit test
  });

  it('does other cool stuff', function () {
    AudioPlayer.doSomething();    
    // unit test
  });

});
谢谢你的帮助

下面是一个JSFIDLE,说明了问题:

我在测试中创建了一个类似单例的上下文,然后用一个返回相同音频上下文的函数来存根构造函数。。。以下是最终测试代码:

describe('AudioPlayer', function () {
  var AudioPlayer;
  var context = new AudioContext();     // create the AudioContext once

  beforeEach(function () {
    module('myApp');

    inject(function ($injector) {
      spyOn(window, 'AudioContext').and.callFake(function () {
        return context;                // stub the constructor
      });
      AudioPlayer = $injector.get('AudioPlayer');
    });
  });

  for (var i=0;i<7;i++) { 
      it('does cool stuff', function () {
        AudioPlayer.doSomething();  
        expect(true).toBe(true);
        // unit test
      });
  }
});
description('AudioPlayer',函数(){
var音频播放器;
var context=new AudioContext();//创建一次AudioContext
beforeach(函数(){
模块(“myApp”);
注入(函数($injector){
spyOn(窗口,'AudioContext')。和.callFake(函数(){
返回上下文;//存根构造函数
});
AudioPlayer=$injector.get('AudioPlayer');
});
});
对于(var i=0;i您可以关闭它

    audioCtx.close();
见文件

你有一个
var self=this;
对吗?另外,请在每次
代码之后添加你的
,用清理部分好,完成。下一步怎么办?我仍然认为你没有显示所有内容,因为
$injector.get('AudioPlayer'))
总是返回服务的同一个静态实例,因此不可能对问题中的每个代码多次调用
new AudioContext();
。下面是一个JSFIDLE:这是当前的正确答案。我不知道
close()
在'15年是否可用。这不正确——在问题中,我说:“我在afterEach块中尝试了AudioPlayer.context.close(),但似乎不起作用。”问题中的示例代码还包含context.close()。在现代浏览器中尝试它仍然会产生相同的结果。不确定为什么它不能像文档中所说的那样工作。为什么是close()它不工作?你有错误吗?你只能在它打开的情况下关闭它。因此需要对state===running或state!==closed进行测试。好的,我看到了。close释放了资源,但是audioCtx仍然存在。所以你可以这样做。如果(audioCtx==null | | audioCtx.state=='closed'){audioCtx=new AudioContext();}在我的实现中起作用