Angular tests, socket.io "NullInjectorError: No provider for WrappedSocket"

4.3k views Asked by At

I'm running tests on angular and they are failing for my socket service thats using ngx-socket-io. It works in development, just not for testing. Its not creating the component correctly.

Test failure

my service.spec.ts

import { TestBed } from '@angular/core/testing';
import { SocketService } from './socket.service';

describe('SocketService', () => {
  let service: SocketService;

  beforeEach(() => {
    TestBed.configureTestingModule({
    });
    service = TestBed.inject(SocketService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

my service

import { Injectable } from '@angular/core';
import {Socket} from 'ngx-socket-io';

@Injectable({
  providedIn: 'root'
})
export class SocketService {
  constructor(private socket: Socket) { }

  getD1Data() {
    return this.createObserver('d1');
  }

  private createObserver(event: string) {
    return this.socket.fromEvent(event);
  }

I have tried adding the provider [WrappedSocket] I'll be honest that was an auto fix option, but that caused way more errors.

import {WrappedSocket} from 'ngx-socket-io/src/socket-io.service';

describe('SocketService', () => {
  let service: SocketService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [WrappedSocket]
    });
    service = TestBed.inject(SocketService);
  });


Error: ./src/app/modules/socket.service.spec.ts
Module not found: Error: Can't resolve 'ngx-socket-io/src/socket-io.service' in 'C:\Users\catha\project - Copy\src\app\modules'

I'm actually not sure how it couldn't exist, considering it was an autofill.

Any ideas on how to fix this? I've tried a range of providers [Socket] , [SocketIOModule] but nothing seems to work

3

There are 3 answers

1
Clive Duncan On

We have to configure the SocketIOModule using the object config of type SocketIoConfig.

... //imports

const config: SocketIoConfig = { url: 'http://localhost:YOUR_PORT' };

describe('SocketService', () => {
  let service: SocketService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ SocketIOModule.forRoot(config) ],
      providers: [ SocketService ]
    });
    service = TestBed.inject(SocketService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

Hopefully this helps!

0
K4liber On

I had the same issue on one machine and doesn't have the issue on another machine. I had the same exact version of packages in both machines. I have made it a little different to avoid the direct use of injectable Socket from ngx-socket-io package:

  1. I have create app-socket.service.ts:
import { Injectable } from '@angular/core';
import { Socket, SocketIoConfig } from 'ngx-socket-io';

const config: SocketIoConfig = { 
    url: 'http://127.0.0.1:8000', 
    options: {
        autoConnect: false
    } 
};

@Injectable({
    providedIn: 'root'
})
export class SocketService extends Socket {

    constructor() {
        super(config)
    }
}
  1. then in the app.module.ts I provided a provider:
  providers: [
    SocketService
  ],
  1. And finally I can inject the provider in my component:
  constructor(
    private socket: SocketService
  )

It works!

0
Althaf On

The angular compiler doesn't know that the service component exists. I was able to solve it by adding service component to the providers in app.module.ts,

@NgModule({
  declarations: [
    
  ],
  imports: [
   
  ],
  providers: [
    SocketService // <- your service
  ],
  bootstrap: [AppComponent],
  entryComponents: [
    
  ],
})

And Make sure the injector is not provided to root.

import { Injectable } from '@angular/core';
import {Socket} from 'ngx-socket-io';

@Injectable() //<- i personaly leave it as empty.
...