Angular中的单元测试socket.io

Posted

技术标签:

【中文标题】Angular中的单元测试socket.io【英文标题】:Unit Testing socket.io in Angular 【发布时间】:2017-11-23 04:30:31 【问题描述】:

我正在尝试在我的应用程序中对 Angular 服务进行单元测试,该服务会创建 socket.io 客户端。我的服务看起来像这样:

export class SocketService 
  private name: string;
  private host: string = window.location.protocol + "//" + window.location.hostname + ":3000";
  socket: io.Socket;

  constructor()  

  subscribeEvent(name: string): Observable<IJobResp> 
    this.setup(name);
    return new Observable(observer => 
      this.socket.on('job', val => observer.next(val))
    )
  

  private setup(name: string) 
    this.name = name;
    let socketUrl = this.host + "/" + this.name;
    this.socket = io.connect(socketUrl);
  

所以为了编写我的测试,我正在使用 mock-socket 库来设置一个 mock socket.io 服务器。这是测试的样子:

describe('SocketService', () => 
  let socket;

  const mockServer = new Server('http://localhost:3000/');
  mockServer.on('connection', server => 
    mockServer.emit('job', 'test message 1');
  );

  (window as any).io = SocketIO;
  beforeEach(() => 
    TestBed.configureTestingModule(
      providers: [JobService]
    );
  );

  it('should xyz, inject([JobService], fakeAsync((service: JobService) => 
    service.subscribeEvent('/').subscribe(val => 
      expect(val).toEqual('test message 1');
    )
  )));
);

但是,该测试会引发错误:

错误:无法从虚假异步测试中生成 XHR。

如果我没有fakeAsync,则在处理subscribe() 中的断言之前测试通过。

我该如何解决这个问题?

更新:

我尝试过的另一种方法是使用async 例如

  it('should subscribe to dwnTime events', async(inject([JobService], (service: JobService) => 
    service.subscribeEvent('line/602').subscribe(val => 
      expect(val).toEqual('test 2');
    )
  )));

然后我得到:

错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。

这看起来像是时间问题,但我仍然不确定为什么?

【问题讨论】:

如果你的服务不引用全局变量,它会更容易测试。为什么不注入 io 或至少导入它以便可以替换它? 【参考方案1】:

您的第二种方法是正确的,因为模拟服务器是真实的,因此您需要通过设置来增加超时

jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;(数值待调整)

describe 函数内的任何位置。

Here你可以找到一个完整的例子。

【讨论】:

以上是关于Angular中的单元测试socket.io的主要内容,如果未能解决你的问题,请参考以下文章

如何对使用 cookie 的 socket.io 中间件进行单元测试

Angular中的单元测试点击事件

Angular2(TypeScript)中的单元测试/模拟窗口属性

Jest 单元测试中的 Angular 循环依赖问题

Angular 单元测试中业力代码覆盖率报告中的 1x 3x 等是啥意思?

询问 Angular 2 单元测试中的 Coverage 摘要?