'assert_called_with always picking up the arguments from the last call
I am very new to python and this is probably something trivial.
I have the following test:
import pytest
from pytest_mock import MockerFixture, call
# Create environment before importing anything from app/.
import makeenv
from data_f import balance_ledger_functions
import orm
from mock_orm import mock_nodes_db
def test_balance_ledger_process_settled(mock_nodes_db: None, mocker: MockerFixture) -> None:
settled_tranaction = created_transaction
settled_tranaction["recent_status"]["status_id"] = "4"
spy = mocker.spy(orm.Nodes, "balance_update")
assert balance_ledger_functions.balance_ledger(created_transaction) == settled_tranaction
to_node_id = settled_tranaction["to"]["id"]
amount = settled_tranaction["amount"]["amount"]
update_transaction_payload = {"balance":"{0}".format(-int(float(amount))), "is_cma" : False, "currency" : "cUSD"}
spy.assert_called_with(to_node_id, update_transaction_payload)
# fees
spy.assert_called_with(
settled_tranaction["fees"][0]["to"]["id"],
{"balance":"{0}".format(-int(float(settled_tranaction["fees"][0]["fee"])))}
)
spy.assert_called_with(
settled_tranaction["fees"][1]["to"]["id"],
{"balance":"{0}".format(-int(float(settled_tranaction["fees"][1]["fee"])))}
)
In the function that we are trying to test the order of the calls are exactly as defined in the test (with different arguments). However, the test is failing with the following error:
> spy.assert_called_with(to_node_id, update_transaction_payload)
E AssertionError: Expected call: balance_update('6156661f7c1c6b71adefbb40', {'balance': '-10000', 'is_cma': False, 'currency': 'cUSD'})
E Actual call: balance_update('559339aa86c273605ccd35df', {'balance': '5'})
Basically, it is asserting the last set of arguments.
What is the correct way to test something like that?
Tried this - didn't work either...
Solution 1:[1]
I created a pytest plugin to help me in those situations: pip install pytest-mock-generator
Once you install it, you'll have the mg
fixture. You can put this line of code in your test and it would print and return the asserts for you: mg.generate_asserts(spy)
.
Here is a complete code example:
Say that you have a python file named example.py
:
def hello(name: str) -> str:
return f"Hello {name}!"
Then you have this test:
import example
def test_spy_list_of_calls(mocker, mg):
example.hello("before spy")
my_spy = mocker.spy(example, "hello")
example.hello("after spy")
example.hello("another after spy")
example.hello("one more time")
mg.generate_asserts(my_spy)
The final line would print this:
from mock import call
assert 3 == my_spy.call_count
my_spy.assert_has_calls(
calls=[call('after spy'), call('another after spy'), call('one more time'), ])
Add those lines to your test and it should work:
import example
from mock import call
def test_spy_list_of_calls(mocker):
example.hello("before spy")
my_spy = mocker.spy(example, "hello")
example.hello("after spy")
example.hello("another after spy")
example.hello("one more time")
assert 3 == my_spy.call_count
my_spy.assert_has_calls(
calls=[call('after spy'), call('another after spy'), call('one more time'), ])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter K |