improbable-eng / grpc-web

gRPC Web implementation for Golang and TypeScript
Apache License 2.0
4.39k stars 436 forks source link

Help mocking a grpc response #1093

Closed maxime1992 closed 2 years ago

maxime1992 commented 2 years ago

I'm using an E2E test runner (Playwright) to test my frontend app.

I'm trying to mock a request (that is using grpc ofc).

But rest assured my request is not about Playwright.

I've been using the encode method followed by the finish one for one message I want to return.

It's not working but I feel like I'm close. By looking at what goes through the network, I feel like I need to wrap that into something. I suspect something like UnaryOutput but it doesn't seem to be exported and maybe it's not that at all.

From my app, not in the e2e sandbox, I can see this in the network:

image

And when I look into the devtool network tab in the e2e test, I cannot see the status being set. So I really feel like I just need to wrap my message into something else, I just don't know what.

Thanks for any help!

maxime1992 commented 2 years ago

Alright after having some help from a colleague and a good fight with all this, I finally got my mock working.

In case anyone else ever need this, here's the code I've ended up with:

const getSomeDataResponseBuffer = GetSomeDataResponse.encode({
  response: {
    $case: 'success',
    success: {
      yourData: {
        // ...
      },
    },
  },
}).finish();

const grpcStatus = Buffer.from('grpc-status:0\r\n');
const grpcMessage = Buffer.from('grpc-message:OK\r\n');
const trailerMessage = Buffer.concat([grpcStatus, grpcMessage]);

const RESPONSE_OK_STATUS = 0;

const grpcResponse = Buffer.concat([
  // status
  new Uint8Array([RESPONSE_OK_STATUS]),
  // bytes defining the length of the message
  new Uint8Array([0, 0, 0, getSomeDataResponseBuffer.byteLength]),
  // the message itself
  getSomeDataResponseBuffer,
  // start of the trailer
  new Uint8Array([0x80]),
  // bytes defining the length of the trailer message
  new Uint8Array([0, 0, 0, trailerMessage.length]),
  trailerMessage,
]);
maxime1992 commented 2 years ago

(also, if there's a better way to do this, please let me know :upside_down_face:)

maxime1992 commented 2 years ago

BTW we've made a complete utility library to wrap all this transparently (that you can use as is) or even with a layer ready to use with Playwright for e2e testing that lets you assert on the calls, responses etc :)

https://github.com/cloudnc/grpc-web-testing-toolbox