douwu8060 2018-12-21 09:35
浏览 571

如何模拟gRPC api与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

  • 写回答

3条回答

  • douzhong1730 2018-12-21 11:05
    关注

    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.

    评论

报告相同问题?