微服务环境下,一个服务依赖另一个服务,如何做集成测试?
How to do integration test for a service that depends on another service in a microservice environment?
我正在构建一个微服务应用程序,目前正在编写一些测试。我正在测试的功能位于 cart
服务所拥有的位置下方,并尝试获取所有购物车商品并将商品详细信息附加到 catalog
服务中每个商品的其他详细信息。
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
}
问题出在测试设置上,我需要将一些测试数据播种到 cart
和 catalog
存储库中。我可以用 cart
回购来做到这一点,但是对于 catalog
来说,只是模拟依赖项 s.CatalogClient.Grpc_GetProductsByIds
是一种常见的做法吗?我对测试还是个新手,据我了解,您通常不会在集成测试中进行模拟,但我不确定是否有更好的方法来解决此类问题。
您是正确的,对于集成测试您不会模拟服务。
通常,如果它是您无法控制的服务,您会存根该服务。
集成测试可以运行针对暂存或测试服务(以 E2E 能力)或在虚拟环境(如 compose、K8S 等)中。
我认为根据您的要求,我会使用 docker-compose 或类似的东西来暂存它。如果您打算将来进行 E2E 设置,您可能需要考虑拥有一个测试环境。
参见:https://www.testenvironmentmanagement.com/types-of-testing-environments/
强制性的“你不应该直接从另一个微服务调用一个微服务”评论。虽然您可以找到使测试工作的方法,但您已将架构紧密耦合。由于您的 cart
服务直接与您的 catalog
服务相关联,因此这个(测试)问题只是第一个问题。如果您解决了 close-coupled architecture 问题,您的测试问题也将得到解决。
我正在构建一个微服务应用程序,目前正在编写一些测试。我正在测试的功能位于 cart
服务所拥有的位置下方,并尝试获取所有购物车商品并将商品详细信息附加到 catalog
服务中每个商品的其他详细信息。
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
}
问题出在测试设置上,我需要将一些测试数据播种到 cart
和 catalog
存储库中。我可以用 cart
回购来做到这一点,但是对于 catalog
来说,只是模拟依赖项 s.CatalogClient.Grpc_GetProductsByIds
是一种常见的做法吗?我对测试还是个新手,据我了解,您通常不会在集成测试中进行模拟,但我不确定是否有更好的方法来解决此类问题。
您是正确的,对于集成测试您不会模拟服务。
通常,如果它是您无法控制的服务,您会存根该服务。
集成测试可以运行针对暂存或测试服务(以 E2E 能力)或在虚拟环境(如 compose、K8S 等)中。
我认为根据您的要求,我会使用 docker-compose 或类似的东西来暂存它。如果您打算将来进行 E2E 设置,您可能需要考虑拥有一个测试环境。
参见:https://www.testenvironmentmanagement.com/types-of-testing-environments/
强制性的“你不应该直接从另一个微服务调用一个微服务”评论。虽然您可以找到使测试工作的方法,但您已将架构紧密耦合。由于您的 cart
服务直接与您的 catalog
服务相关联,因此这个(测试)问题只是第一个问题。如果您解决了 close-coupled architecture 问题,您的测试问题也将得到解决。