3

This test works.

def test_mock_ingest():
    with mock.patch('app.ingest.ingest') as mock_ingest:
        app.ingest.ingest('test-data', {'test-key': 'test-value'})
        assert mock_ingest.call_count == 1

This test fails because mock_ingest.call_count = 0

def test_mock_ingest():
    with mock.patch('app.ingest.ingest') as mock_ingest:
        call_function_that_runs_async_code()
        assert mock_ingest.call_count == 1

call_function_that_runs_async_code calls the app.ingest.ingest function.

I know because I can see that the test data is ingested.

But for some reason, mock_ingest.call_count is still 0.

I think it has to do with the fact that the code that runs app.ingest.ingest is async.

Edit:

I'm using python 3.8.

I also tried this without success:

```python
def test_mock_ingest():
    with mock.patch('app.ingest.ingest', new_callable=mock.AsyncMock) as mock_ingest:
        call_function_that_runs_async_code()
        assert mock_ingest.call_count == 1
6
  • Did you try the following? def test_mock_ingest(): with patch.object(app.ingest, 'ingest') as mock_ingest: call_function_that_runs_async_code() mock_ingest.assert_called_once() Commented Dec 21, 2020 at 20:29
  • Does this answer your question? Mocking async call in python 3.5 Commented Dec 21, 2020 at 20:29
  • @DolevP Yes but I read somewhere there are gotchas with that method so I'm relying on call_count instead. Commented Dec 21, 2020 at 20:41
  • @code11 I tried new_callable=mock.AsyncMock in python 3.8 also. Will add that to my question. Commented Dec 21, 2020 at 20:42
  • I see. My point wasn't just using assert_called_once() instead of call_count, but rather using patch.object instead of patch. Commented Dec 21, 2020 at 20:46

1 Answer 1

2

The solution had nothing to do with async code after all.

call_function_that_runs_async_code wasn't calling app.ingest.ingest.

It was calling ingest after ingest was imported like this: from app.ingest import ingest.

That import is correct but due to namespace issues with mocking, importing the function in different ways across application code and test code does not work.

TIL that you patch functions where you import them, not where they are defined. https://docs.python.org/3/library/unittest.mock.html#where-to-patch

The correct solution code in my example should look like this:

def test_mock_ingest():
    with mock.patch('async_codebase.ingest') as mock_ingest:
        call_function_that_runs_async_code()
        assert mock_ingest.call_count == 1

where async_codebase includes the import:

from app.ingest import ingest
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.