I've been facing an issue while using unitttest.mock and pytest to Mock a dependency class into another one.
I'm testing a class Card that receives an GenericAPI class into its constructor.
The GenericAPI class has the following:
class GenericAPI(CardAPI):
REQUEST = {
'API': 'xxx',
'CARDS_ENDPOINT': 'xxx',
'DELAY': 0.1,
'ENCODING': 'utf-8',
'HEADER_AUTH': {'Authorization': 'Bearer cs{client_secret}'},
'HEADER_CONTENT': {'Content-Type': 'application/json'},
}
def __init__(self, name):
super().__init__(self)
self.name = name
self._value = None
def get_card(self, name):
try:
response = requests.get(url=f'{self.REQUEST["API"]}{self.REQUEST["CARDS_ENDPOINT"]}?exact={name}')
response.raise_for_status()
return response.json()
except requests.HTTPError as err:
logger.debug(f'Card "{name}" not found. trying fuzzy match. Response: {err}')
try:
response = requests.get(url=f'{self.REQUEST["API"]}{self.REQUEST["CARDS_ENDPOINT"]}?fuzzy={name}')
response.raise_for_status()
return response.json()
except requests.HTTPError as err:
logger.debug(f'Card "{name}" not found. Response: {err}')
raise ValueError
@property
def value(self):
return self._value
@value.getter
def value(self):
prices = self.get_card(name=self.name)['prices']
self.value = dict({'foil': prices['usd_foil'], 'non-foil': prices['usd']})
return self._value
@value.setter
def value(self, new_value):
self._value = new_value
And the Card class that depends on it is defined by
class Card:
def __new__(cls, *args, **kwargs):
try:
kwargs['external_api'].get_card(name=kwargs['name'])
return super(Card, cls).__new__(cls)
except ValueError:
raise ValueError('Unable to instantiate Card with current value as it is not a valid card')
def __init__(self, name, set_name=None, condition=None, foil=None, external_api=None):
self.name = name
self.set_name = set_name
self.condition = condition
self.foil = foil
self._value = None
self._external_api = external_api
@property
def value(self):
return float(self.value)
@value.getter
def value(self):
card = self._external_api(name=self.name)
price = card.value
if self.foil:
self.value = price['foil']
return self._value
else:
self.value = price['non-foil']
return self._value
@value.setter
def value(self, new_value):
self._value = new_value
The Test is defined as follows:
@pytest.fixture
def mock_external_api():
m = MagicMock(spec=GenericAPI)
m.get_card.return_value = good_response
type(m).value = PropertyMock(return_value=good_response['prices'])
print(m.value)
return m
class TestCard:
def test_card_price_is_float(self, mock_external_api):
card = Card(name='mox opal', external_api=mock_external_api)
assert isinstance(card.value, float)
The error is the following:
=============================================================================================== FAILURES ================================================================================================
___________________________________________________________________________________ TestCard.test_card_price_is_float ____________________________________________________________________________________
self = <test_card.TestCard object at 0x7f3ffdbeffd0>, mock_external_api = <MagicMock spec='ScryfallAPI' id='139912816342632'>
def test_card_price_is_float(self, mock_external_api):
card = Card(name='mox opal', external_api=mock_external_api)
> assert isinstance(card.value, float)
E AssertionError: assert False
E + where False = isinstance(<MagicMock name='mock().value.__getitem__()' id='139912816374616'>, float)
E + where <MagicMock name='mock().value.__getitem__()' id='139912816374616'> = (<class 'collection_app.cards.Card'>, {'name': 'mox opal', 'set_name': None, 'condition': None, 'foil': None, '_value'...ck().value.__getitem__()' id='139912816374616'>, '_external_api': <MagicMock spec='GenericAPI' id='139912816342632'>}).value
collection_app/tests/unit/test_card.py:37: AssertionError
----------------------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------------------------
{'usd': '91.40', 'usd_foil': '111.66', 'eur': '69.87', 'tix': '30.29'}
=================================================================================== 1 failed, 2 passed in 0.16 seconds ===================================================================================
What could be the mistake here? I took my time to read the unittest.mock docs yet I don't seem to grasp what is missing here.
Aucun commentaire:
Enregistrer un commentaire