Reputation: 4643
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
Upvotes: 3
Views: 804
Reputation: 4643
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
Upvotes: 2