Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock gRPC api for integration testing with golang

all

I have a service written in go which communicates with a couple of other services via gRPC protocol. I want to write integration tests for my service but, I have no possibility to use real dependencies.

So, I need to mock the dependencies in some way.

For me, a perfect scenario looks like:

  • I can run a mock-server and pass its address instead of a real dependency to my application
  • I can register expected response for a specific call to the dependant service
  • I can reset the mock-server to tear down the data after a test case.

I tried to use https://github.com/jekiapp/gripmock but it doesn't support all the protobuff syntax.

What can help with my problem? Maybe I'm completely wrong and there are best practices for integration testing of services communicating gRPC

like image 567
Maxim Schepelin Avatar asked Dec 21 '18 09:12

Maxim Schepelin


2 Answers

You can spin up your environment by defining all of your services in a docker-compose file. You should add the service you want to test as well in the docker-compose file. After spinning it up you can run your integration tests in the service you want to test.

Example docker-compose file:

version: '2.2'

services:
  service-you-want-to-test:
    build: .
    image: service-you-want-to-test
    container_name: service-you-want-to-test
    environment:
      - ENVIRONMENT=${ENVIRONMENT}
      - REDIS_ADDRESSES=[redis:6379]
      - SERVICE_YOU_DEPEND_ON_ENDPOINT=service-you-depend-on:8091
      - DB_HOST=mysql
      - DB_USER=root
    links:
      - redis
      - mysql
      - service-you-depend-on
    depends_on:
      mysql:
        condition: service_healthy
    ports:
      - 8090:8090

  service-you-depend-on:
    image: service-you-depend-on:latest
    container_name: service-you-depend-on
    environment:
      - DB_HOST=mysql
      - DB_USER=root
    links:
      - redis
      - mysql
    depends_on:
      mysql:
        condition: service_healthy
    ports:
      - 8091:8091

  mysql:
    image: mysql:5.7
    container_name: mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
    volumes:
    - ./.docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    - ./.docker/mysql/healthcheck-5.7:/var/www/healthcheck
    healthcheck:
      test: "/var/www/healthcheck"
      interval: 5s
      timeout: 5s
      retries: 5
    ports:
    - 3306:3306

  redis:
    image: redis:3.2
    container_name: redis
    ports:
      - 6379:6379

To set up your integration environment you can use these commands:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
docker build -t service-you-want-to-test .
docker-compose up -d redis mysql
docker-compose up -d --build service-you-want-to-test

After running the above you can just execute your integration tests via the command line:

go test -v path/to/integration_tests/...

So you should add the services that you depend on to the docker-compose file as well so you can actually send a request to them in your integration tests. Be sure to add those service endpoints in your environment variables so you can override the endpoint you send your request to.

For resetting your data in for example your database you can write fixtures. The fixtures are just helper functions to reset the data of your database, cache, etc.

like image 188
Sefa Avatar answered Sep 27 '22 22:09

Sefa


Another alternative tool that you can use in this situation is Traffic Parrot.

We recently added support for gRPC to our service virtualization tool which includes a user interface that can be used to define the mock behaviour.

There is a tutorial on how to mock gRPC responses over the wire given a proto file.

You can also find information on how to record and replay over the wire in the documentation.

Traffic Parrot gRPC user interface Recording gRPC messages Replaying gRPC messages

like image 45
Liam Williams Avatar answered Sep 27 '22 21:09

Liam Williams