Пропустить реализацию в Jest - PullRequest
0 голосов
/ 29 января 2020

В настоящее время у меня есть следующий фрагмент кода:

function handleConnection(socket: Socket): void {
  info(`Connection started with socketId: ${socket.id}`)

  socket.on("joinRoom", (request: string) => handleJoinRoom(socket, request));

  socket.on("shareData", (request: IShareDataRequest) => handleShareData(socket, request));

  socket.on("disconnect", () => handleDisconnect(socket));
}

Я хочу написать тест для каждого события, такого как joinRoom, shareData и disconnect. Чтобы изолировать тесты, я хочу протестировать только второй socket.on("shareData", () => ...) вызов и пропустить первый socket.on("joinRoom", () => ...) вызов. Я пытался с несколькими mockImplementationOnce методами безуспешно.

Тест, который я написал:

it('should emit data to room', () => {
    const listenMock = listen();
    const socketMock = {
      on: jest.fn()
        .mockImplementationOnce(() => null)
        .mockImplementationOnce((event: string, callback: Function) => callback({ roomId: "abcdefg" })),
      to: jest.fn().mockReturnValue({
        emit: jest.fn()
      })
    }
    jest.spyOn(listenMock, "on").mockImplementationOnce((event: string, callback: Function) => callback(socketMock))

    startSocket();

    expect(socketMock.to).toHaveBeenCalledWith("abcdefg");
    expect(socketMock.to().emit).toHaveBeenCalledWith("receiveData", expect.any(Object));
  })

Функция ShareData:

function handleShareData(socket: Socket, request: IShareDataRequest): void {
  socket.to(request.roomId).emit("receiveData", request);
}

Я был бы очень признателен если кто-нибудь может помочь мне с этим.

1 Ответ

1 голос
/ 29 января 2020

Вы можете попробовать следующий подход:

// define the mockSocket
const mockSocket = {
  // without any implementation
  on: jest.fn()
};

describe("connection handler", () => {
  // I personally like separating the test setup
  // in beforeAll blocks 
  beforeAll(() => {
    handleConnection(mockSocket);
  });

  // you can write assertions that .on
  // should have been called for each event
  // with a callback
  describe.each(["joinRoom", "shareData", "disconnect"])(
    "for event %s",
    event => {
      it("should attach joinRoom handlers", () => {
        expect(mockSocket.on.mock.calls).toEqual(
          expect.arrayContaining([[event, expect.any(Function)]])
        );
      });
    }
  );

  describe("joinRoom handler", () => {
    beforeAll(() => {
      // jest mock functions keep the calls internally
      // and you can use them to find the call with 
      // the event that you need and retrieve the callback
      const [_, joinRoomHandler] = mockSocket.on.mock.calls.find(
        ([eventName]) => eventName === "joinRoom"
      );

      // and then call it
      joinRoomHandler("mockRequestString");
    });

    it("should handle the event properly", () => {
      // your joinRoom handler assertions would go here
    });
  });
});
...