unit-testingdjango-testingpython-mock

Mock Stripe Methods in Python for testing


So I am trying to mock all the stripe web hooks in the method so that I can write the Unit test for it. I am using the mock library for mocking the stripe methods. Here is the method I am trying to mock:

class AddCardView(APIView):
"""
* Add card for the customer
"""

permission_classes = (
    CustomerPermission,
)

def post(self, request, format=None):
    name = request.DATA.get('name', None)
    cvc = request.DATA.get('cvc', None)
    number = request.DATA.get('number', None)
    expiry = request.DATA.get('expiry', None)

    expiry_month, expiry_year = expiry.split("/")

    customer_obj = request.user.contact.business.customer

    customer = stripe.Customer.retrieve(customer_obj.stripe_id)

    try:
        card = customer.sources.create(
            source={
                "object": "card",
                "number": number,
                "exp_month": expiry_month,
                "exp_year": expiry_year,
                "cvc": cvc,
                "name": name
            }
        )
        # making it the default card
        customer.default_source = card.id
        customer.save()
    except CardError as ce:
        logger.error("Got CardError for customer_id={0}, CardError={1}".format(customer_obj.pk, ce.json_body))
        return Response({"success": False, "error": "Failed to add card"})
    else:
        customer_obj.card_last_4 = card.get('last4')
        customer_obj.card_kind = card.get('type', '')
        customer_obj.card_fingerprint = card.get('fingerprint')
        customer_obj.save()

    return Response({"success": True})

This is the method for unit testing:

@mock.patch('stripe.Customer.retrieve')
@mock.patch('stripe.Customer.create')
def test_add_card(self,create_mock,retrieve_mock):
    response = {
        'default_card': None,
        'cards': {
            "count": 0,
            "data": []
        }
    }

    # save_mock.return_value = response
    create_mock.return_value = response
    retrieve_mock.return_value = response

    self.api_client.client.login(username = self.username, password = self.password)
    res = self.api_client.post('/biz/api/auth/card/add')

    print res

Now stripe.Customer.retrieve is being mocked properly. But I am not able to mock customer.sources.create. I am really stuck on this.


Solution

  • This is the right way of doing it:

    
    @mock.patch('stripe.Customer.retrieve')
    def test_add_card_failure(self, retrieve_mock):
        data = {
            'name': "shubham",
            'cvc': 123,
            'number': "4242424242424242",
            'expiry': "12/23",
        }
        e = CardError("Card Error", "", "")
        retrieve_mock.return_value.sources.create.return_value = e
    
        self.api_client.client.login(username=self.username, password=self.password)
    
        res = self.api_client.post('/biz/api/auth/card/add', data=data)
    
        self.assertEqual(self.deserialize(res)['success'], False)