最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Testing gRPC functions - Stack Overflow

programmeradmin0浏览0评论

I have a task to test gRPC client call functions with Jest. Here is what a typical node.js function looks like:

client.authenticate(request, meta, (error, response) => {
   if (!error) {
      console.log('REPLY FROM SERVER: ', response)
   } else {
    console.error(error)
  }
})

Procedure calls are callback functions, as we see I can not export response object to outside variable. The above function is the one I need to test. I need to check if the function has been called with no error. How do I do it with jest? Been struggling for a while now.

I have a task to test gRPC client call functions with Jest. Here is what a typical node.js function looks like:

client.authenticate(request, meta, (error, response) => {
   if (!error) {
      console.log('REPLY FROM SERVER: ', response)
   } else {
    console.error(error)
  }
})

Procedure calls are callback functions, as we see I can not export response object to outside variable. The above function is the one I need to test. I need to check if the function has been called with no error. How do I do it with jest? Been struggling for a while now.

Share Improve this question edited Jun 5, 2020 at 12:31 Aika Sat asked Jun 5, 2020 at 12:04 Aika SatAika Sat 1813 silver badges12 bronze badges 1
  • If you want to test this end-to-end, you would need to have Jest check your console to see if 'REPLY FROM SERVER' has been printed or not, as that's the only thing visible to the user after this function is called. – Sean Chapman Commented Sep 18, 2020 at 8:42
Add a ment  | 

3 Answers 3

Reset to default 5

You can use jest.spyOn(object, methodName) to mock client.authenticate.

E.g.

index.ts:

import { client } from './client';

export function main() {
  const request = {};
  const meta = {};
  client.authenticate(request, meta, (error, response) => {
    if (!error) {
      console.log('REPLY FROM SERVER: ', response);
    } else {
      console.error(error);
    }
  });
}

client.ts:

export const client = {
  authenticate(request, meta, callback) {
    console.log('real implementation');
  },
};

index.test.ts:

import { main } from './';
import { client } from './client';

describe('62214949', () => {
  it('should log correct response', () => {
    const mResponse = 'mocked response';
    const logSpy = jest.spyOn(console, 'log');
    jest.spyOn(client, 'authenticate').mockImplementationOnce((request, meta, callback) => {
      console.log('mocked implementation');
      callback(null, mResponse);
    });
    main();
    expect(logSpy).toBeCalledWith('REPLY FROM SERVER: ', 'mocked response');
    expect(client.authenticate).toBeCalledWith({}, {}, expect.any(Function));
  });

  it('should handle error', () => {
    const mError = new Error('network');
    const logSpy = jest.spyOn(console, 'error');
    jest.spyOn(client, 'authenticate').mockImplementationOnce((request, meta, callback) => {
      console.log('mocked implementation');
      callback(mError);
    });
    main();
    expect(logSpy).toBeCalledWith(mError);
    expect(client.authenticate).toBeCalledWith({}, {}, expect.any(Function));
  });
});

unit test result with coverage report:

 PASS  stackoverflow/62214949/index.test.ts (10.557s)
  62214949
    ✓ should log correct response (23ms)
    ✓ should handle error (8ms)

  console.log
    mocked implementation

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

  console.log
    REPLY FROM SERVER:  mocked response

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

  console.log
    mocked implementation

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

  console.error
    Error: network
        at Object.<anonymous> (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/stackoverflow/62214949/index.test.ts:18:20)
        at Object.asyncJestTest (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
        at resolve (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:45:12)
        at new Promise (<anonymous>)
        at mapper (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:28:19)
        at promise.then (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:75:41)
        at process._tickCallback (internal/process/next_tick.js:68:7)

       8 |       console.log('REPLY FROM SERVER: ', response);
       9 |     } else {
    > 10 |       console.error(error);
         |               ^
      11 |     }
      12 |   });
      13 | }

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)
      at stackoverflow/62214949/index.ts:10:15
      at Object.<anonymous> (stackoverflow/62214949/index.test.ts:22:7)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |      90 |      100 |   66.67 |      90 |                   
 client.ts |      50 |      100 |       0 |      50 | 3                 
 index.ts  |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        12.424s

I got a very similar problem: we use Cypress to test a React App which uses GRPC-Web protocol to municate with GRPC backends.

Almost every library out there to mock GRPC backends requires starting a full server along with your testing suite, which is pretty inconvenient and annoying in CI environments.

So I decided to make a small package that stimulates the part of the backend network which is responsible for encoding responses for gRPC-web clients. We use it in bination with Cypress and its network interception feature. So we can intercept a GRPC call and inject a mocked response during E2E tests.

https://www.npmjs./package/@botchris/grpc-web-mock

try this git mock repo, it provides mock responses. U need to create mock grpc server and add rpc method from the proto file. you can provide your actual responses in rules. grpc-mock

发布评论

评论列表(0)

  1. 暂无评论