Overriding multiple invocations of the same macro in a unit test

Consider the following unit test:

toy_model.sql:

select 
 {{ dbt_utils.star(ref('source_a'), except=some_columns) }},
 {{ dbt_utils.star(ref('source_b'), except=some_columns) }}
from source_a 
join source_b using (join_key)

unit_test.yml

unit_tests:
  - name: model_unit_test
    model: toy_model
    overrides:
       macros:
         dbt_utils.star:  col_a,  col_b
  ...

How can I override the 2 invocations of dbt_utils.star separately? They need to return different columns. Is there a way to separately override multiple invocations of the same macro in a unit test?

I was hoping that something like this might work:

  overrides:
      macros:
         dbt_utils.star:  
           - col_a,  col_b  # first invocation
           - col_c,  col_d # second invocation

But unsurprisingly, it doesn’t (it would be in the docs otherwise).

Thanks in advance for any help or hint!

I don’t think there’s a way to do that at the moment.

Note: @Jeremy Yeo originally posted this reply in Slack. It might not have transferred perfectly.

1 Like

Yes, I think so too. Only workaround I could find is to define separate wrapper macros:

macros.sql

{% macro get_source_a_columns(except=[]) %}
   {{ dbt_utils.star(ref('source_a'), except=except) }},
{% endmacro %}

{% macro get_source_b_columns(except=[]) %}
   {{ dbt_utils.star(ref('source_b'), except=except) }},
{% endmacro %}

Then use those in the model:

toy_model.sql:

select 
 {{ get_source_a_coumns(except=some_columns) }},
 {{ get_source_b_coumns(except=some_columns) }}
from source_a 
join source_b using (join_key)

Less than ideal, but I guess the best you can do at the moment.

it’s interesting, when asking an AI (Gemini) this question, it spits out the above workaround, but also this interesting nugget:

overrides:
   macros:
     dbt_utils.star: |
       {% macro star(relation, except=[], __invocation_id=none) %}
         {% if __invocation_id == 'source_a' %}
           col_a, col_b
         {% elif __invocation_id == 'source_b' %}
           col_c, col_d
         {% else %}
           -- Default behavior or error handling
           ''
         {% endif %}
       {% endmacro %}

which overrides the macro definition in the test. When I saw that I really hoped it would work, alas, it doesn’t, at least not for me. dbt parses the macro definition alright, but it clearly expects the override to be the literal result of the macro invocation, not a redefinition of it.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.