Investigate mocking recursing further than required #144
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
The
dbt-unit-testing
SQL Builder macrobuild_model_complete_sql
contains thebuild_model_dependencies
sub-macro which recursively traverses the DAG in a depth-first fashion to gather the list of nodes of the DAG which must be synthesized. It takes a list of mocked nodes as a second parameter and short-circuits the recursion if the current node is mocked. This list of mocked nodes is passed to the first invocation ofbuild_model_dependencies
but is not passed in the subsequent calls meaning that in the case where the mocked model or source is not referenced directly from the model under test all dependencies are mocked.Existing Behavior in sql_builders.sql
Desired Behavior in sql_builders.sql
Impact
Under ordinary circumstances this generates a larger test-query than is strictly needed but does not have other negative impact. In our dbt environment we use the
dbt-fal
adapter to bring our own runtime fordbt-python
models.dbt-unit-testing
reads the contents of models inject into the mocked CTEs (while resolvingsource
/ref
call to allow this recursively). When the recursive step reads a python model the resulting CTE is invalid SQL (it's Python code!) and the test fails.Additional Details
It is unclear to me how to test this directly within the current testing framework. If it is acceptable that it is untested I am fine with that (assuming the rest of the change is green in CI). If you feel we should test that I'd love a pointer as to how we might do that.
I have wrapped the
debug
macro code in a variable condition the same wayverbose
operated before to add some debugging steps here. I am happy to pull that all back or create a separate PR for it. Thedebug
macro is not in use elsewhere so this felt reasonable for now but I'm happy to trim this down to the one-liner chage.Steps to reproduce
dbt init ...
and setup the config/profilesdbt-unit-testing
with the following package file. Uncomment the upstream and rundbt deps
to see the existing behavior. Uncomment the fork/revision version to see the new behaviormodels/example/
:in1.sql
intermediate_model.sql
passthrough.sql
final.sql
tests/unit/
:final-mock-intermediate.sql
Results
Before
Before this change the
in1
initial model is referenced and resolved in the generated test query as generated with the command$ dbt test --vars '{"verbose": "true"}' -s final-mock-intermediate
After
With this change, which provides the list of mocks to short-circuit recursion, CTE resolution stops at
intermediate_model
as it is mocked in the test.