How to do integration test for a service that depends on another service in a microservice environment?

1.4k views Asked by At

I am building a microservice app, and currently writing some tests. The function that I am testing is below where it's owned by cart service and tries to get all cart items and append the item details with other details of each item from catalog service.

func (s *Server) Grpc_GetCartItems(ctx context.Context, in *pb.GetCartItemsRequest) (*pb.ItemsResponse, error) {
    // Get product ids and its quantity in cart by userId
    res, err := s.Repo.GetCartItems(ctx, in.UserId)
    if err != nil {
        return nil, err
    }

    // Return empty response if there is no items in cart
    if len(res) == 0 {
        return &pb.ItemsResponse{}, nil
    }

    // Get Product ID Keys from map
    ids := GetMapKeys(res)

    // RPC call catalog server to get cart products' names
    products, err := s.CatalogClient.Grpc_GetProductsByIds(ctx, &catalogpb.GetProductsByIdsRequest{ProductIds: ids})
    if err != nil{
        return nil, err
    }

    // Return response in format product id, product name, and qty in cart
    items, err := AppendItemToResponse(products, res)
    if err != nil{
        return nil, err
    }

    return items, nil
}

The problem is for the test setup, I need to seed some test data to both of the cart and catalog repositories. I can do that with cart repo just fine, but for the catalog is it a common practice to just mock the dependency s.CatalogClient.Grpc_GetProductsByIds instead? I am still new to testing, and from what I understand you generally don't do mocking in integration tests, but I am not sure if there's a better way to tackle this kind of issue.

2

There are 2 answers

2
Ale8k On BEST ANSWER

You're correct in that for an integration test you would not mock a service.

Usually, if it is a service you do not have control over, you would stub the service.

Integration tests can be run against staging or testing services (in an E2E capacity) or in a virtual environment (like compose, K8S, etc.).

I think for your requirement, I would stage it using docker-compose or something similar. If you intend to go for an E2E setup in the future, you may want to look into having a testing environment.

See: https://www.testenvironmentmanagement.com/types-of-testing-environments/

3
meshtron On

Obligatory "you should not be calling one microservice directly from another" comment. While you can find a way to make testing work, you've tightly coupled the architecture. This (testing) concern is only the first of what will become many since your cart service directly ties to your catalog service. If you fix you close-coupled architecture problem, your testing problem will also be resolved.