如何在Node中模拟一个流数据的端点?

huangapple go评论58阅读模式
英文:

How do I mock an endpoint that streams data in Node?

问题

Here's the translated code portion you provided:

我有一个返回换行分隔的JSON流数据ndjson的端点我正在尝试在jest中模拟它以进行单元测试我尝试了几种方法来使它工作但无法正确执行这是我目前的代码

import * as fetch from 'node-fetch';
const ndjson = require('ndjson');
import getEvents from './getEvents';
import { EventResponseBody } from '../mocks/mockData';

describe('Events resolver', () => {

  let fetchMock: jest.SpyInstance;
  
  beforeAll(() => {
    fetchMock = jest.spyOn(fetch, 'default').mockImplementation(() => undefined);
  });

  afterEach(() => {
    fetchMock.mockReset();
  });

  afterAll(() => {
    fetchMock.mockRestore();
  });

  it('为id返回事件', async () => {
    const response = new fetch.Response(ndjson.stringify(EventsResponseBody), {status: 200})
    fetchMock.mockReturnValue(Promise.resolve(response));

    await getEvents(url, token, { id: '1' });
    expect(fetchMock).toHaveBeenCalledTimes(1);
  });
});

请注意,这只是代码的部分翻译。如果您需要有关代码的更多详细信息或其他帮助,请告诉我。

英文:

I have an endpoint that returns streaming data as newline-delimited json (ndjson). I'm trying to mock it in jest for a unit test. I've tried several ways to make this work but can't get it right. Here's what I have currently:

import * as fetch from 'node-fetch';
const ndjson = require('ndjson');
import getEvents from './getEvents';
import { EventResponseBody } from '../mocks/mockData'

describe('Events resolver', () => {

  let fetchMock: jest.SpyInstance;
  
  beforeAll(() => {
    fetchMock = jest.spyOn(fetch, 'default').mockImplementation(() => undefined);
  });

  afterEach(() => {
    fetchMock.mockReset();
  });

  afterAll(() => {
    fetchMock.mockRestore();
  });

  it('returns events for an id', async () => {
    const response = new fetch.Response(ndjson.stringify(EventsResponseBody), {status: 200})
    fetchMock.mockReturnValue(Promise.resolve(response));

    await getEvents(url, token, { id: '1' });
    expect(fetchMock).toHaveBeenCalledTimes(1);
  });
});

This code runs without error, but the test fails with a timeout error: thrown: "Exceeded timeout of 5000ms". ndjson.stringify() returns a Transform stream; do I need to explicitly emit data on that stream? If it helps, here's (working) code that utilizes the endpoint:

getEvents = (url, token, params) => (
  new Promise<T>(async (resolve, reject) => {
    const resp = fetch(url + params, {
      headers: {
        Accept: 'application/x-ndjson',
        Authorization: `Bearer ${token}`,
      },
    })
      .then(response => {
        const events = []
        response.body.pipe(ndjson.parse()).on('data', data =>
          events.push(data)
        ).on('end', () => {
          resolve(events)
        });
    }).catch(e => reject(e))
  });

Any help would be appreciated.

答案1

得分: 0

以下是您要翻译的内容:

"答案实际上非常简单;我应该在Node中阅读有关流使用的信息。只需创建一个流(在我的代码中,使用ndjson.stringify()完成此操作),将其返回到响应主体,然后进行写入。"

英文:

The answer is actually pretty straightforward; I should have read up on stream usage in Node. Simply create a stream (in my code this is done with ndjson.stringify()), return it in the response body, then write to it.

it('returns timeline updates for an identity', async () => {

    const eventsStream = ndjson.stringify();

    const response = new fetch.Response(eventsStream, {status: 200})
    fetchMock.mockReturnValue(Promise.resolve(response));
 
    EventsResponseData.forEach((json: String) => {
      eventsStream.write(json)
    })
    eventsStream.end()

    await getUpdates({}, { identityId: '1' }, {});
    expect(fetchMock).toHaveBeenCalledTimes(1);
  });

huangapple
  • 本文由 发表于 2023年4月20日 01:11:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76057175.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定