1+ import * as ProtoLoader from '@grpc/proto-loader' ;
12import { INestApplication } from '@nestjs/common' ;
23import { Transport } from '@nestjs/microservices' ;
34import { Test } from '@nestjs/testing' ;
5+ import { fail } from 'assert' ;
6+ import { expect } from 'chai' ;
7+ import * as GRPC from 'grpc' ;
48import { join } from 'path' ;
59import * as request from 'supertest' ;
610import { GrpcController } from '../src/grpc/grpc.controller' ;
711
812describe ( 'GRPC transport' , ( ) => {
913 let server ;
1014 let app : INestApplication ;
15+ let client : any ;
1116
12- beforeEach ( async ( ) => {
17+ before ( async ( ) => {
1318 const module = await Test . createTestingModule ( {
1419 controllers : [ GrpcController ] ,
1520 } ) . compile ( ) ;
@@ -24,18 +29,83 @@ describe('GRPC transport', () => {
2429 protoPath : join ( __dirname , '../src/grpc/math.proto' ) ,
2530 } ,
2631 } ) ;
32+ // Start gRPC microservice
2733 await app . startAllMicroservicesAsync ( ) ;
2834 await app . init ( ) ;
35+ // Load proto-buffers for test gRPC dispatch
36+ const proto = ProtoLoader . loadSync (
37+ join ( __dirname , '../src/grpc/math.proto' ) ,
38+ ) as any ;
39+ // Create Raw gRPC client object
40+ const protoGRPC = GRPC . loadPackageDefinition ( proto ) as any ;
41+ // Create client connected to started services at standard 5000 port
42+ client = new protoGRPC . math . Math (
43+ 'localhost:5000' ,
44+ GRPC . credentials . createInsecure ( ) ,
45+ ) ;
2946 } ) ;
3047
31- it ( `/ POST` , ( ) => {
48+ it ( `GRPC Sending and Receiving HTTP POST` , ( ) => {
3249 return request ( server )
3350 . post ( '/' )
3451 . send ( [ 1 , 2 , 3 , 4 , 5 ] )
3552 . expect ( 200 , { result : 15 } ) ;
3653 } ) ;
3754
38- afterEach ( async ( ) => {
55+ it ( 'GRPC Sending and receiving Stream from RX handler' , async ( ) => {
56+ const callHandler = client . SumStream ( ) ;
57+
58+ callHandler . on ( 'data' , ( msg : number ) => {
59+ expect ( msg ) . to . eql ( { result : 15 } ) ;
60+ callHandler . cancel ( ) ;
61+ } ) ;
62+
63+ callHandler . on ( 'error' , ( err : any ) => {
64+ // We want to fail only on real errors while Cancellation error
65+ // is expected
66+ if (
67+ String ( err )
68+ . toLowerCase ( )
69+ . indexOf ( 'cancelled' ) === - 1
70+ ) {
71+ fail ( 'gRPC Stream error happened, error: ' + err ) ;
72+ }
73+ } ) ;
74+
75+ return new Promise ( ( resolve , reject ) => {
76+ callHandler . write ( { data : [ 1 , 2 , 3 , 4 , 5 ] } ) ;
77+ setTimeout ( ( ) => resolve ( ) , 1000 ) ;
78+ } ) ;
79+ } ) ;
80+
81+ it ( 'GRPC Sending and receiving Stream from Call Passthrough handler' , async ( ) => {
82+ const callHandler = client . SumStreamPass ( ) ;
83+
84+ callHandler . on ( 'data' , ( msg : number ) => {
85+ expect ( msg ) . to . eql ( { result : 15 } ) ;
86+ callHandler . cancel ( ) ;
87+ } ) ;
88+
89+ callHandler . on ( 'error' , ( err : any ) => {
90+ // We want to fail only on real errors while Cancellation error
91+ // is expected
92+ if (
93+ String ( err )
94+ . toLowerCase ( )
95+ . indexOf ( 'cancelled' ) === - 1
96+ ) {
97+ fail ( 'gRPC Stream error happened, error: ' + err ) ;
98+ }
99+ } ) ;
100+
101+ return new Promise ( ( resolve , reject ) => {
102+ callHandler . write ( { data : [ 1 , 2 , 3 , 4 , 5 ] } ) ;
103+ setTimeout ( ( ) => resolve ( ) , 1000 ) ;
104+ } ) ;
105+ } ) ;
106+
107+ after ( async ( ) => {
39108 await app . close ( ) ;
109+ client . close ( ) ;
40110 } ) ;
41111} ) ;
0 commit comments