Mi aplicación consiste principalmente en CRUD hacia/desde MongoDB usando el paquete mongo-go-drive . Esta función es uno de los servicios del servidor gRPC y todo lo que hace es llamar al método de la base de datos action.GetProducts(ctx) y devuelve *mongo.cursor . Luego se decodifica el resultado. Para cada documento, coloco el contenido del documento en una estructura de producto singular, luego lo agrego a las porciones de productos (la estructura GetProductsResponse se crea usando el tipo repeated GetProductResponse del protogRPC). Después de agregar todo el producto en GetProductsResponse , devuelvo la respuesta al cliente gRPC.
También soy nuevo en las pruebas en general, ¿cómo debo desglosar la función y hacer la simulación (¿cómo burlarse del cursor?) para las pruebas unitarias? ¿Es necesario en primer lugar hacer una prueba unitaria en la función a pesar de que todo lo que hace es agregar el resultado, o debería ir directamente a la prueba de integración y omitir la prueba unitaria ya que involucra E / S de la base de datos?
func (s *Server) GetProducts(ctx context.Context, in *pb.EmptyRequest) (*pb.GetProductsResponse, error) { cursor, err := action.GetProducts(ctx) if err != nil { return nil, err } products := pb.GetProductsResponse{} res := model.Product{} for cursor.Next(ctx) { // Convert document to above struct err := cursor.Decode(&res) if err != nil { return nil, fmt.Errorf("failed to decode document: %v", err) } product := &pb.GetProductResponse{ProductId: res.Product_id.Hex(), Name: res.Name, Price: res.Price, Qty: int32(res.Qty)} products.Products = append(products.Products, product) } return &products, nil }Si interactúa con la base de datos, ya no es una prueba unitaria, porque se está integrando con otro sistema externo.
De todos modos, suelo definir mi función de capa "repositorio" de esta manera:
package repo var FetchUserById = func(id string) (*model.User, error){ // here the real logic return user, err }y luego, cuando tengo que probar la lógica de mi capa de "servicio", me burlo de toda la capa de "repositorio" de esta manera:
repo.FetchUserById = func(id string) (*model.User, err) { return myMockedUser, nil }