Does pytest-mock have an equivalent for call()? I agree for mocking in general 
we should consider replacing plain decorators and context managers with the 
mocker fixture. This probably deserves its own discussion thread.
 
--
Sent from my iPhone

> On 10 Jul 2025, at 14:37, Dev-iL <gid....@gmail.com> wrote:
> 
> One tiny comment regarding TP's suggestion - IMHO it's better to avoid 
> `unittest.mock` in favor of the equivalent `mocker` fixture provided by 
> `pytest-mock`.
> 
> On 2025/07/10 06:30:22 Tzu-ping Chung wrote:
> > Personally I dislike things like assert_called_once_with etc. since they 
> > are easy to miss when you scan a test to see what they are trying to check. 
> > An 'assert' keyword stands out (it’s always the first word in the line), 
> > especially with syntax highlighting.
> >
> > I do agree the proposed Pytest style is arguably less readable. I offer 
> > another syntax.
> >
> >
> > from unittest.mock import call
> >
> > assert mock_http_run.mock_calls == [
> > call(
> > endpoint=f"api/v2/accounts/{expected_account_id}/",
> > data=None,
> > extra_options=None,
> > )
> > ]
> > assert mock_paginate.mock_calls == []
> >
> >
> > To me, this is on par with assert_called_once_with et al. in terms of 
> > readability, and arguably better for test authors since you don’t need to 
> > remember the various function names anymore, but only 'mock_calls' and the 
> > 'call' helper class.
> >
> > TP
> >
> >
> > > On Jul 9, 2025, at 23:28, Ferruzzi, Dennis <fe...@amazon.com.INVALID> 
> > > wrote:
> > >
> > > I'm a bit late to the party, and really only reiterating what has already 
> > > been said, but of the two examples (original and your rewrite, I prefer 
> > > the original. I think as a general rule, we tend to use the 
> > > assert_called_once, etc with mocks butt he asserts with non-mocked 
> > > variables.
> > >
> > > I am all for more documentation, but I'd have a slight preference towards 
> > > keeping the existing structure.
> > >
> > >
> > > - ferruzzi
> > >
> > >
> > > ________________________________
> > > From: Kyungjun Lee <ky...@gmail.com>
> > > Sent: Tuesday, July 8, 2025 2:13 AM
> > > To: dev@airflow.apache.org
> > > Subject: RE: [EXT] [DISCUSS] Consistent test assertion style: 
> > > pytest-native vs unittest-style
> > >
> > > CAUTION: This email originated from outside of the organization. Do not 
> > > click links or open attachments unless you can confirm the sender and 
> > > know the content is safe.
> > >
> > >
> > >
> > > AVERTISSEMENT: Ce courrier électronique provient d’un expéditeur externe. 
> > > Ne cliquez sur aucun lien et n’ouvrez aucune pièce jointe si vous ne 
> > > pouvez pas confirmer l’identité de l’expéditeur et si vous n’êtes pas 
> > > certain que le contenu ne présente aucun risque.
> > >
> > >
> > >
> > > Thank you Ash and Amogh Desai for your insights and explanations.
> > > The information you shared has been incredibly helpful and is contributing
> > > a lot to my growth.
> > >
> > > 2025년 7월 8일 (화) 오후 2:54, Amogh Desai <am...@gmail.com>님이 작성:
> > >
> > >> Agreed, I personally also find the current way to be easier to read and 
> > >> in
> > >> most
> > >> cases we want to assert if "something" was called, irrespective of the
> > >> order it was
> > >> called in. So the dedicated function based way works well for me.
> > >>
> > >> If I want to test a order, I'd rather call parts of code that I want to
> > >> test explicitly and assert
> > >> on them.
> > >>
> > >>> This happens because the mock object is not properly recognized as a 
> > >>> mock
> > >> instance at type-checking time, which might confuse some contributors,
> > >> especially new ones relying on type hints or static analysis tools.
> > >>
> > >> Regarding this, I'd say you can either cast mocks to their types as one
> > >> way:
> > >> `mock_http_run: MagicMock = mock_http_run` -- give or take, or use
> > >> `autospec` to make the mock reflect the signature of the object? Check 
> > >> out:
> > >> https://docs.python.org/3/library/unittest.mock.html#autospeccing
> > >>
> > >> Thanks & Regards,
> > >> Amogh Desai
> > >>
> > >>
> > >> On Mon, Jul 7, 2025 at 6:13 PM Ash Berlin-Taylor <as...@apache.org> 
> > >> wrote:
> > >>
> > >>> def test_get_account(self, mock_paginate: Mock, mock_http_run: Mocj,
> > >>> conn_id, account_id):
> > >>>
> > >>>
> > >>> Might fix that? IDEs in general do not cope well with purest tests, and
> > >>> are missing context on what most of the variables are, be it
> > >> parameterised
> > >>> values or fixture values, so this isn’t a problem that is unique to
> > >> mocks.
> > >>>
> > >>>> On 7 Jul 2025, at 12:47, Kyungjun Lee <ky...@gmail.com>
> > >> wrote:
> > >>>>
> > >>>> I'd like to follow up on our previous discussion about pytest-native vs
> > >>>> unittest-style assertions.
> > >>>>
> > >>>> While working on the following test case:
> > >>>>
> > >>>> ```python
> > >>>>
> > >>>> @pytest.mark.parametrize(
> > >>>> argnames="conn_id, account_id",
> > >>>> argvalues=[(ACCOUNT_ID_CONN, None), (NO_ACCOUNT_ID_CONN,
> > >> ACCOUNT_ID)],
> > >>>> ids=["default_account", "explicit_account"],
> > >>>> )
> > >>>> @patch.object(DbtCloudHook, "run")
> > >>>> @patch.object(DbtCloudHook, "_paginate")
> > >>>> def test_get_account(self, mock_paginate, mock_http_run, conn_id,
> > >>>> account_id):
> > >>>> hook = DbtCloudHook(conn_id)
> > >>>> hook.get_account(account_id=account_id)
> > >>>>
> > >>>> assert hook.method == "GET"
> > >>>>
> > >>>> _account_id = account_id or DEFAULT_ACCOUNT_ID
> > >>>> hook.run.assert_called_once_with(
> > >>>> endpoint=f"api/v2/accounts/{_account_id}/", data=None,
> > >>>> extra_options=None
> > >>>> )
> > >>>> hook._paginate.assert_not_called()
> > >>>>
> > >>>> ```
> > >>>>
> > >>>> My IDE shows a warning:
> > >>>> Cannot find reference 'assert_called_once_with' in 'function'.
> > >>>>
> > >>>> This happens because the mock object is not properly recognized as a
> > >> mock
> > >>>> instance at type-checking time, which might confuse some contributors,
> > >>>> especially new ones relying on type hints or static analysis tools.
> > >>>>
> > >>>> I realized that this aspect of mock handling might be missing from our
> > >>>> previous discussions. I wanted to bring it up as part of the broader
> > >>>> conversation about test styles—particularly how we balance IDE/tooling
> > >>>> support with readability and style consistency.
> > >>>>
> > >>>> Curious to hear your thoughts on this!
> > >>>>
> > >>>> @ash @potiuk
> > >>>>
> > >>>> 2025년 7월 6일 (일) 오후 8:09, Kyungjun Lee <ky...@gmail.com>님이 작성:
> > >>>>
> > >>>>> Thank you @Potiuk for pointing out the intent behind the “one assert
> > >> per
> > >>>>> test” principle, and @ash for highlighting how using dedicated mock
> > >>> assert
> > >>>>> functions can make the code easier to read and understand. These were
> > >>>>> perspectives I hadn’t fully considered, and I really appreciate you
> > >>> sharing
> > >>>>> them.
> > >>>>>
> > >>>>> Thanks to your input, I was able to read more materials and broaden my
> > >>>>> thinking on the topic. That said, my original focus was more on the
> > >> idea
> > >>>>> that sticking to plain assert statements lowers the entry barrier for
> > >>> new
> > >>>>> contributors—because they don’t have to learn multiple assertion
> > >> styles.
> > >>>>>
> > >>>>> Still, as @Potiuk mentioned, I’ll put more thought into making the
> > >>> testing
> > >>>>> guidelines clearer and more concrete—especially since that helps
> > >>> AI-based
> > >>>>> tools as well 😄
> > >>>>>
> > >>>>> For reference, here’s one of the articles I read:
> > >>>>> https://medium.com/@kentbeck_7670/test-desiderata-94150638a4b3
> > >>>>>
> > >>>>> Thank you to everyone who took part in this discussion.
> > >>>>>
> > >>>>> 2025년 7월 6일 (일) 오후 3:42, Ash Berlin-Taylor <as...@apache.org>님이 작성:
> > >>>>>
> > >>>>>> I personally find the dedicated functions way easier to read the
> > >> intent
> > >>>>>> behind, it’s one function/statement vs 3. More so when you don’t care
> > >>> about
> > >>>>>> the order of calls, just that something was called (where to do this
> > >>>>>> manually we’d need to reimplement the helper function)
> > >>>>>>
> > >>>>>> Additionally pytest already rewrites those to have nicer error
> > >>> messages,
> > >>>>>> but the dedicated mock assert finding are much easier to read the
> > >> code
> > >>> and
> > >>>>>> understand the intent to me, so I’i am for staying with the dedicated
> > >>>>>> assert functions
> > >>>>>>
> > >>>>>> -ash
> > >>>>>>
> > >>>>>>> On 5 Jul 2025, at 13:30, Kyungjun Lee <ky...@gmail.com>
> > >>> wrote:
> > >>>>>>>
> > >>>>>>> I’ve learned a lot of things I didn’t know before.
> > >>>>>>> Thank you so much for all your help — I really appreciate it.
> > >>>>>>> I’ll get started on this right away!
> > >>>>>>>
> > >>>>>>> 2025년 7월 5일 (토) 오후 9:18, Jarek Potiuk <ja...@potiuk.com>님이 작성:
> > >>>>>>>
> > >>>>>>>>> Haha ... I'm curious — which part sounded like ChatGPT style?
> > >>>>>>>> English isn't my first language, so I did get a little help from
> > >> it.
> > >>>>>>>>
> > >>>>>>>> That whole paragraph :) .
> > >>>>>>>>
> > >>>>>>>>>> Sure! Since you asked for how the test *should* be written, I
> > >> took
> > >>>>>> the
> > >>>>>>>> opportunity to clean it up using a more pytest-native style while
> > >>> also
> > >>>>>>>> fixing the mock order issue.
> > >>>>>>>>
> > >>>>>>>> "Sure! Since you asked ..." sounds like an AI bot.
> > >>>>>>>>
> > >>>>>>>>> That got me thinking — what do you think about adding a guideline
> > >>>>>>>> document
> > >>>>>>>> for writing tests, similar to how we have a coding style guide?
> > >>>>>>>>
> > >>>>>>>> Absolutely - we already have some "seed' of it "Writing tests"
> > >>>>>> chapter in
> > >>>>>>>> contributing guideline, but we could definitely make it more
> > >>> detailed.
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>
> > >>>
> > >> https://github.com/apache/airflow/blob/main/contributing-docs/testing/unit_tests.rst#writing-unit-tests
> > >>>>>>>>
> > >>>>>>>> And - speaking of AI - this is becoming more and more important to
> > >>>>>> describe
> > >>>>>>>> any common rules we have and context - so that using Agentic AI
> > >>> yields
> > >>>>>>>> better results. Kaxil already added
> > >>>>>>>> https://github.com/apache/airflow/blob/main/AGENTS.md which
> > >>> describes
> > >>>>>>>> context for coding agents lile Codex - and we could improve it and
> > >>> link
> > >>>>>>>> more docs from our repo if they get more of our agreed
> > >> "conventions"
> > >>> -
> > >>>>>> then
> > >>>>>>>> Agents would get it as context and their generated code would be
> > >>>>>> consistent
> > >>>>>>>> with what we describe there.
> > >>>>>>>>
> > >>>>>>>> In a way - I think having a good documentation on processes, tools
> > >>> and
> > >>>>>>>> conventions was always something I've been after, but with the
> > >>> Agentic
> > >>>>>>>> workflows it might significantly boost the quality of generated
> > >> code
> > >>>>>> if we
> > >>>>>>>> have more of those conventions and guidelines described.
> > >>>>>>>>
> > >>>>>>>> So .... ABSOLUTELY ... the more we describe in there, the better.
> > >> And
> > >>>>>> we
> > >>>>>>>> have no more excuse that "anyhow no-one reads it" - because the
> > >>> coding
> > >>>>>>>> agents WILL be reading it and acting accordingly. So I think this
> > >> is
> > >>> a
> > >>>>>> very
> > >>>>>>>> good investment to make.
> > >>>>>>>>
> > >>>>>>>> J.
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>> On Sat, Jul 5, 2025 at 2:07 PM Kyungjun Lee <
> > >>> kyungjunlee...@gmail.com
> > >>>>>>>
> > >>>>>>>>> wrote:
> > >>>>>>>>>
> > >>>>>>>>> Haha ... I'm curious — which part sounded like ChatGPT style?
> > >>>>>>>>> English isn't my first language, so I did get a little help from
> > >> it.
> > >>>>>>>>>
> > >>>>>>>>> But thank you — I actually learned something new from your
> > >> comment!
> > >>>>>>>>> That got me thinking — what do you think about adding a guideline
> > >>>>>>>> document
> > >>>>>>>>> for writing tests, similar to how we have a coding style guide? It
> > >>>>>> might
> > >>>>>>>>> help ensure consistency across the Airflow codebase when it comes
> > >> to
> > >>>>>>>>> testing styles as well.
> > >>>>>>>>>
> > >>>>>>>>> 2025년 7월 5일 (토) 오후 8:52, Jarek Potiuk <ja...@potiuk.com>님이 작성:
> > >>>>>>>>>
> > >>>>>>>>>> But of course - i'd love to hear what others think - it's not a
> > >>> "very
> > >>>>>>>>>> strong" opinion.
> > >>>>>>>>>>
> > >>>>>>>>>> On Sat, Jul 5, 2025 at 1:48 PM Jarek Potiuk <ja...@potiuk.com>
> > >>>>>> wrote:
> > >>>>>>>>>>
> > >>>>>>>>>>> Cool. That's what I wanted to see.
> > >>>>>>>>>>>
> > >>>>>>>>>>> By the way - not that there's anything wrong - but was the
> > >> answer
> > >>>>>>>>> written
> > >>>>>>>>>>> by AI initially ? The first paragraph looks suspiciously like
> > >> Chat
> > >>>>>>>> GPT
> > >>>>>>>>>>> answer :D ?
> > >>>>>>>>>>>
> > >>>>>>>>>>> Comment from my side: I personally prefer the original style.
> > >> It's
> > >>>>>>>> more
> > >>>>>>>>>>> concise and it is easier to read - you see as if the call was
> > >>>>>>>> actually
> > >>>>>>>>>>> written down. Also this is quite a bit too many assertions in
> > >> the
> > >>>>>>>>> second
> > >>>>>>>>>>> case and it takes a lot of mental effort to understand what
> > >>> actually
> > >>>>>>>> is
> > >>>>>>>>>>> being asserted.
> > >>>>>>>>>>>
> > >>>>>>>>>>> There is a "school" of writing unit tests that every test should
> > >>>>>> have
> > >>>>>>>>> ONE
> > >>>>>>>>>>> assertion only. Always. I think it is a bit extreme, and I do
> > >> not
> > >>>>>>>>> follow
> > >>>>>>>>>> it
> > >>>>>>>>>>> myself but I think it is also a kind of good direction to have
> > >> ->
> > >>>>>> the
> > >>>>>>>>>> fewer
> > >>>>>>>>>>> assertions you have in your test, the better (I think).
> > >>>>>>>>>>>
> > >>>>>>>>>>> I think tests should be mostly optimized for easiness of reading
> > >>> and
> > >>>>>>>>>>> understanding what is being tested - and it's just not that easy
> > >>> in
> > >>>>>>>> the
> > >>>>>>>>>>> second case.
> > >>>>>>>>>>>
> > >>>>>>>>>>> J.
> > >>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>>
> > >>>>>>>>>>> On Sat, Jul 5, 2025 at 1:39 PM Kyungjun Lee <
> > >>>>>>>> kyungjunlee...@gmail.com>
> > >>>>>>>>>>> wrote:
> > >>>>>>>>>>>
> > >>>>>>>>>>>> Sure! Since you asked for how the test *should* be written, I
> > >>> took
> > >>>>>>>> the
> > >>>>>>>>>>>> opportunity to clean it up using a more pytest-native style
> > >> while
> > >>>>>>>> also
> > >>>>>>>>>>>> fixing the mock order issue.
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Here’s the updated test:
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> ```python
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> @pytest.mark.parametrize(
> > >>>>>>>>>>>> argnames="conn_id, account_id",
> > >>>>>>>>>>>> argvalues=[(ACCOUNT_ID_CONN, None), (NO_ACCOUNT_ID_CONN,
> > >>>>>>>>>> ACCOUNT_ID)],
> > >>>>>>>>>>>> ids=["default_account", "explicit_account"],
> > >>>>>>>>>>>> )
> > >>>>>>>>>>>> @patch.object(DbtCloudHook, "run")
> > >>>>>>>>>>>> @patch.object(DbtCloudHook, "_paginate")
> > >>>>>>>>>>>> def test_get_account(self, mock_paginate, mock_http_run,
> > >> conn_id,
> > >>>>>>>>>>>> account_id):
> > >>>>>>>>>>>> hook = DbtCloudHook(conn_id)
> > >>>>>>>>>>>> hook.get_account(account_id=account_id)
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> assert hook.method == "GET"
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> expected_account_id = account_id or DEFAULT_ACCOUNT_ID
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> assert mock_http_run.call_count == 1
> > >>>>>>>>>>>> assert mock_http_run.call_args.args == ()
> > >>>>>>>>>>>> assert mock_http_run.call_args.kwargs == {
> > >>>>>>>>>>>> "endpoint": f"api/v2/accounts/{expected_account_id}/",
> > >>>>>>>>>>>> "data": None,
> > >>>>>>>>>>>> "extra_options": None,
> > >>>>>>>>>>>> }
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> assert mock_paginate.call_count == 0
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> ```
> > >>>>>>>>>>>> Why I chose this style:
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> -
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> *Mock verification using assert*: Instead of
> > >>>>>>>>>>>> mock.assert_called_once_with(...), I used call_count and
> > >>>>>>>> call_args.
> > >>>>>>>>>>>> This
> > >>>>>>>>>>>> approach aligns better with pytest’s idioms and produces
> > >>> cleaner,
> > >>>>>>>>>> more
> > >>>>>>>>>>>> readable error messages when assertions fail.
> > >>>>>>>>>>>> -
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> *Explicit verification*: Using call_args.args and
> > >>>>>>>> call_args.kwargs
> > >>>>>>>>>>>> makes
> > >>>>>>>>>>>> the test behavior very explicit, which helps with debugging
> > >> and
> > >>>>>>>>>>>> understanding the exact calls made.
> > >>>>>>>>>>>> -
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> *Decorator order matching argument order*: As @patch
> > >> decorators
> > >>>>>>>>> apply
> > >>>>>>>>>>>> from the bottom up, the argument order has been corrected to
> > >>>>>>>> match
> > >>>>>>>>> (
> > >>>>>>>>>>>> mock_paginate first, then mock_http_run).
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> Let me know if you'd like to follow a slightly different
> > >>> convention
> > >>>>>>>> —
> > >>>>>>>>>>>> happy
> > >>>>>>>>>>>> to adjust!
> > >>>>>>>>>>>>
> > >>>>>>>>>>>> I was lu
> [message truncated...]

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@airflow.apache.org
For additional commands, e-mail: dev-h...@airflow.apache.org

Reply via email to