вернуть читаемый макет из иглы с помощью nock - тест отфильтрованного потока Twitter

Я пытаюсь в течение нескольких часов и все еще пытаюсь правильно проверить свое соединение с потоком с фильтром Twitter.

Вот как выглядит мой класс, который я хочу протестировать:

import { injectable } from 'inversify';
import { ReadableStream } from 'needle';
import needle from 'needle';

@injectable()
export class TwitterStreamAdapter {
  public stream: ReadableStream | undefined;

  public startStream = (): void => {
    const streamUrl = process.env.TWITTER_STREAM_URL as string;
    this.stream = needle.get(streamUrl, { // <<----- I WANT TO TEST THIS 
      headers: { Authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}` },
    });

    this.stream
      .on('data', (data) => {
        try {
          console.log(JSON.parse(data));
        } catch (e) {
          // Keep alive signal received. Do nothing.
        }
      })
  };
}

Короче говоря, здесь я создаю соединение с api отфильтрованного потока твиттера, который постоянно поддерживается и является потоком, в который отправляются твиты.

Во-первых, я хочу проверить, получаю ли я правильный поток от needle.get хотя вы, вероятно, можете возразить, что я пытаюсь протестировать библиотеку вместо своей реализации.

Потерпите минутку и посмотрите тест ниже:

  beforeEach(() => (twitterStreamAdapter = new TwitterStreamAdapter()));

  it('connects to filtered stream and returns stream', (done) => {
    const host = 'https://api.twitter.com';
    const path = '/2/tweets/search/stream';
    const mockedStream = new PassThrough(); // <<---- I want to be able to emit with this stream
    const scope = nock(host, {
      reqheaders: {
        authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
      },
    })
      .get(path)
      .delay(2000)
      .reply(200, () => mockedStream);

    twitterStreamAdapter.startStream();

    twitterStreamAdapter.stream!.emit('data', { message: 'hello world'}); // <<--- this works, but I don't want to use the prop of the instance to emit

    mockedStream.emit('data', 'hello world 2'); // <<---- this doesn't work, I'd like to use mockedStream to emit

    expect(twitterStreamAdapter.stream).toEqual(mockedStream); // <<--- this expectation fails
  });

Здесь, в тесте, я хотел бы создать mockedStream, и я бы хотел, чтобы этот поток возвращался из needle.get. Таким образом, у меня будет больше контроля над своими тестами. Во-первых, мне бы не пришлось делать свойство моего классаthis.stream общественность.

В тесте Вы видите, что я делаю twitterStreamAdapter.stream.emit который работает и генерирует событие, которое передается обратному вызову this.stream.on('data' ...) что вы можете увидеть в реализации метода классов.

Также в тесте есть такая строка:

expect(twitterStreamAdapter.stream).toEqual(mockedStream);

Как на самом деле я могу проверить, возвращается ли правильный поток (фиктивный) из needle.get.

Честно говоря, я немного запутался во всем этом, я впервые пытаюсь протестировать запрос, который действительно остается активным и возвращает потоки данных.

Любая помощь очень ценится!

ИЗМЕНИТЬ ---- на основе того, что я исследовал до сих пор -----, но все еще есть проблемы:

Пока что я переписал свой текущий тестовый код так:

it('handles stream data event', async (done) => {
    const mockedResponse = { message: 'hello from nock' };

    nock(host, {
      reqheaders: {
        authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
      },
    })
      .get(path)
      .reply(200, () => mockedResponse);

    twitterStreamAdapter.startStream();
    const stream: ReadableStream | undefined = twitterStreamAdapter.stream;

    jest.spyOn(JSON, 'parse');

    stream!.on('data', () => {
      expect(JSON.parse).toHaveBeenCalledWith({ message: 'hello from nock' });
      done();
    });
  });

Здесь я успешно получаю data событие запущено, и тест работает. Проблема в том, что я пытаюсь запустить (испустить) error событие.

Я старался:

nock(...).get(path).replyWithError({code: 'ETIMEDOUT'});

а также:

nock(...).get(path).reply(500);

И он не излучает error событие.

0 ответов

Другие вопросы по тегам