Как установить соединение с websocket в модульных тестах Angular? - PullRequest
0 голосов
/ 27 августа 2018

Я работаю над приложением Angular (v 6.1.0), которое взаимодействует с бэкэндом через веб-сокет. Пока что все работает нормально, кроме модульного тестирования. Я создал фиктивный бэкэнд для тестирования моих компонентов, но я просто не могу установить соединение между фиктивным бэкэндом и модулями тестирования. Я использую Jasmine как библиотеку утверждений, а Jest - как тестовый, это пример набора тестов:

describe('RandomComponent', () => {
  let component: RandomComponent;
  let fixture: ComponentFixture<RandomComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [],
      imports: [SomeModule],
      providers: [SpecialWebSocketService, WebSocketService,
        { provide: BackendUrlService, useClass: BackendUrlMockService }
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(RandomComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create random component', () => {
      expect(component).toBeTruthy();
  });
});

BackendUrlMockService предназначен только для предоставления URL. Один тестовый пример выдает следующее:

 FAIL  src/app/path/to/my/random.component.spec.ts
  RandomComponent
    ✕ should create random component (603ms)

  ● RandomComponent › should create random component

    InvalidStateError: Still in CONNECTING state.

Приложение отлично работает как с реальным бэкэндом, так и с поддельным. Модули тестирования не работают ни с одним из них. Я также заметил, что если я добавлю таймаут в тестовый случай:

it('should create random component', (done) => {
  setTimeout(() => {
    expect(component).toBeTruthy();
    done();
  }, 1000);
});

Мой фиктивный бэкэнд регистрирует сообщение о том, что соединение установлено правильно, но я все еще получаю сообщение об ошибке. У кого-нибудь есть идеи, как правильно все настроить, чтобы я мог протестировать свои компоненты?

1 Ответ

0 голосов
/ 27 августа 2018

На основании комментария @ user184994 я решил смоделировать веб-сокет вместо бэкэнда:

const mockData = {
  // some arbitrary data
};

class WebSocketServiceSpy {

  private messageSpy = new Subject<string>();
  private messageHandler = this.messageSpy.asObservable();

  createObservableSocket(url: string): Observable<string> {
    console.log(`Websocket would connect to ${url}.`);

   return new Observable(observer => {
      this.messageHandler.subscribe(() => {
        observer.next(JSON.stringify(mockData));
      });
    });
  }

  sendMessage(message: any) {
    this.messageSpy.next();
  }
}

Затем я использовал его в модуле тестирования:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [],
    imports: [SomeModule],
      providers: [SpecialWebSocketService, BackendUrlService,
        { provide: WebSocketService, useClass: WebSocketServiceSpy }  
    ]
  })
    .compileComponents();
}));

И тест наконец-то зеленый:

PASS  src/app/path/to/my/random.component.spec.ts
 ● Console

   console.log src/app/path/to/my/random.component.spec.ts:911
     Websocket would connect to <actual url>.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...