impl(bigquery): add BigQuery::from_stub to support client mocking - #6620
impl(bigquery): add BigQuery::from_stub to support client mocking#6620alvarowolfx wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a public stub module re-exporting client mocking traits and adds a from_stub constructor to the BigQuery client to facilitate testing with mock stubs, accompanied by comprehensive unit and integration tests. Feedback on the changes highlights a compilation issue in from_stub where stub.into() must be explicitly called, and suggests using the local crate::stub::JobService path rather than the external crate path to maintain API consistency.
| pub fn from_stub<T>(stub: impl Into<std::sync::Arc<T>>) -> Self | ||
| where | ||
| T: google_cloud_bigquery_v2::stub::JobService + 'static, | ||
| { | ||
| Self { | ||
| job_service: Arc::new(JobService::from_stub(stub)), | ||
| project_id: None, | ||
| } | ||
| } |
There was a problem hiding this comment.
There are two issues with the current implementation of from_stub:
- Compilation Error: The
stubparameter is of typeimpl Into<std::sync::Arc<T>>, butJobService::from_stubexpectsstd::sync::Arc<T>. Since Rust does not perform implicit type conversions for function arguments, you must explicitly callstub.into()to convert it. - Path Consistency: Since this PR introduces
crate::stub::JobServiceas a public re-export, we should use it here instead of the fully-qualified external pathgoogle_cloud_bigquery_v2::stub::JobServiceto maintain consistency and clean API boundaries.
Here is the corrected implementation:
| pub fn from_stub<T>(stub: impl Into<std::sync::Arc<T>>) -> Self | |
| where | |
| T: google_cloud_bigquery_v2::stub::JobService + 'static, | |
| { | |
| Self { | |
| job_service: Arc::new(JobService::from_stub(stub)), | |
| project_id: None, | |
| } | |
| } | |
| pub fn from_stub<T>(stub: impl Into<std::sync::Arc<T>>) -> Self | |
| where | |
| T: crate::stub::JobService + 'static, | |
| { | |
| Self { | |
| job_service: Arc::new(JobService::from_stub(stub.into())), | |
| project_id: None, | |
| } | |
| } |
There was a problem hiding this comment.
no compilation errors, but on the second path AI is right. Similar to reasons why we removed crate::model, should we also skip adding crate::stub ? Thoughts @dbolduc ?
Also I'm trying to decide how from_stub is going to work in a world where we also support Storage API acceleration.
- We can add a
from_storage_stubthat accepts both ? - We change
from_stubto accept a trait has all methods on both JobService and Read client ? - Another option ?
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6620 +/- ##
=======================================
Coverage 96.53% 96.53%
=======================================
Files 306 306
Lines 93503 93521 +18
=======================================
+ Hits 90267 90285 +18
Misses 3236 3236 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
dbolduc
left a comment
There was a problem hiding this comment.
It seems weird to expect the application to know which RPC on JobService gets called for a given query. And we might route them differently later?
I think the ideal looks more like defining a custom stub that mirrors the client::BigQuery surface. So there is only mock.expect_query() and we would publicize the synthetic request that has all the fields.
Aside: we settled for less than ideal for mocking LROs / paginated APIs. They look more like this where the application has to unroll the client library behavior. https://googleapis.github.io/google-cloud-rust/mocking_lros.html
Also FWIW: we did not sign up to do mocking for v1, so feel free to defer this.
Fixes #6357