I'm trying to mock a response in a small function using some pyscard attributes.
My function:
def card_reader():
# request any card type
cardtype = AnyCardType()
cardrequest = CardRequest(timeout=25, cardType=cardtype)
cardservice = cardrequest.waitforcard()
# attach the console tracer
observer = ConsoleCardConnectionObserver()
cardservice.connection.addObserver(observer)
# connect to the card and perform a few transmits
cardservice.connection.connect()
try:
response, sw1, sw2 = cardservice.connection.transmit(ADPU)
except SWException as e:
print(str(e))
cardservice.connection.disconnect()
And my mock:
@patch("my_module.temp_card_reader.CardRequest")
def test_card_reader(mock_card_request):
mock_card_request.return_value.connection.transmit.return_value = (200, 201, 203)
result = card_reader()
Using my test, I can mock until cardservice.connection.connect()
, but I can't go forward to return a value that I want.
I've always been intrigued by Mocks, MagicMocks and my apparent lack of knowledge about them 😂, that's why I was curious about this.
I could totally be wrong, but I think what is happening is the following:
CardRequest
.cardservice = cardrequest.waitforcard()
.waitforcard()
is defined, the MagicMock() says "Oh... ok... I guess I'll return a blank (default?) MagicMock here" (meaning: cardservice
is a default MagicMock)I think (I've tested but I'm not super-confident, since I'm missing the actual code) that the solution is to tell the CardRequest
mock something along the lines of: "Hey, when they call .waitforcard()
, don't return a blank (default?) MagicMock, but rather THIS mock_cardservice
mock which knows how to handle the .transmit
method"
So maaaybe mocking a cardservice
would work:
@patch("my_module.temp_card_reader.CardRequest")
def test_card_reader(mock_card_request):
mock_cardservice = MagicMock()
mock_cardservice.connection.transmit.return_value = (200, 201, 203)
mock_card_request.return_value.waitforcard.return_value = mock_cardservice
result = card_reader()
With this, I've been able to see 200 201 203
if I do a print right after cardservice.connection.transmit(ADPU)
:
response, sw1, sw2 = cardservice.connection.transmit(ADPU)
print(response, sw1, sw2)