英文:
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) {
// 通过用户ID获取购物车中的产品ID和数量
res, err := s.Repo.GetCartItems(ctx, in.UserId)
if err != nil {
return nil, err
}
// 如果购物车中没有任何项,则返回空响应
if len(res) == 0 {
return &pb.ItemsResponse{}, nil
}
// 从映射中获取产品ID键
ids := GetMapKeys(res)
// 调用catalog服务以获取购物车产品的名称
products, err := s.CatalogClient.Grpc_GetProductsByIds(ctx, &catalogpb.GetProductsByIdsRequest{ProductIds: ids})
if err != nil{
return nil, err
}
// 以产品ID、产品名称和购物车中的数量的格式返回响应
items, err := AppendItemToResponse(products, res)
if err != nil{
return nil, err
}
return items, nil
}
问题是在测试设置中,我需要向cart
和catalog
存储库中添加一些测试数据。我可以很好地使用cart
存储库完成这个操作,但是对于catalog
存储库,是否常见的做法是只模拟依赖项s.CatalogClient.Grpc_GetProductsByIds
呢?我对测试还不太熟悉,从我所了解的来看,通常不会在集成测试中进行模拟,但我不确定是否有更好的方法来解决这种问题。
英文:
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.
答案1
得分: 0
你在说的没错,对于集成测试,你不会模拟一个服务。
通常情况下,如果是一个你无法控制的服务,你会对该服务进行存根处理。
集成测试可以针对暂存或测试服务进行运行(以端到端的方式),或者在虚拟环境中运行(如compose、K8S等)。
根据你的需求,我建议你使用docker-compose或类似的工具进行暂存。如果你打算在将来进行端到端设置,你可能需要考虑建立一个测试环境。
参考链接:https://www.testenvironmentmanagement.com/types-of-testing-environments/
英文:
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/
答案2
得分: 0
强制性的“你不应该直接从一个微服务调用另一个微服务”的评论。虽然你可以找到一种方法使测试工作,但你已经将架构紧密耦合起来。这个(测试)问题只是你的“购物车”服务直接与你的“目录”服务相关联的众多问题中的第一个。如果你解决了你的紧密耦合架构问题,你的测试问题也将得到解决。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论