Context
I am developing an API Rest with Django Rest Framework, and some of my endpoints consume an external API Rest to create a model instance, the code works but right now I am trying to test my code but I have very struggled with that. I am a little beginner developing tests and maybe the question is very obvious but, I tried so many things, with the below links but I couldn't achieve it.
Mocking external API for testing with Python
How do I mock a third party library inside a Django Rest Framework endpoint while testing?
https://realpython.com/testing-third-party-apis-with-mocks/
Codes
This is my view
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from app.lnd_client import new_address
from app.models import Wallet
from api.serializers import WalletSerializer
class WalletViewSet(viewsets.ModelViewSet):
queryset = Wallet.objects.all()
serializer_class = WalletSerializer
lookup_field = "address"
@action(methods=["post"], detail=False)
def new_address(self, request):
response = new_address()
if "error" in response.keys():
return Response(
data={"error": response["error"]}, status=response["status_code"]
)
else:
return Response(response)
def create(self, request, *args, **kwargs):
response = self.new_address(self)
if response.status_code >= 400:
return response
serializer = self.get_serializer(data=response.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data, status=status.HTTP_201_CREATED, headers=headers
)
This is my client with the call to the external api
import requests
from django.conf import settings
from typing import Dict
endpoint = settings.LND_REST["ENDPOINT"]
endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
endpoint = (
"https://" + endpoint if not endpoint.startswith("http") else endpoint
)
endpoint = endpoint
auth = {"Grpc-Metadata-macaroon": settings.LND_REST["MACAROON"]}
cert = settings.LND_REST["CERT"]
def new_address() -> Dict:
try:
r = requests.get(
f"{endpoint}/v1/newaddress", headers=auth, verify=cert
)
r.raise_for_status()
except requests.exceptions.HTTPError as errh:
return {
"error": errh.response.text,
"status_code": errh.response.status_code,
}
except requests.exceptions.RequestException:
return {
"error": f"Unable to connect to {endpoint}",
"status_code": 500,
}
return r.json()
My test is this
from django.urls import reverse
from nose.tools import eq_
from rest_framework.test import APITestCase
from unittest.mock import patch
from rest_framework import status
from .factories import WalletFactory
from app.lnd_client import new_address
class TestWalletListTestCase(APITestCase):
def setUp(self):
WalletFactory.create_batch(5)
self.url = reverse("wallet-list")
self.wallet_data = WalletFactory.generate_address()
def test_get_all_wallets(self):
response = self.client.get(self.url)
eq_(response.status_code, status.HTTP_200_OK)
#This is the problem test
@patch('app.lnd_client.requests.post')
def test_create_wallet(self,mock_method):
mock_method.return_value.ok = True
response = self.client.post(self.url)
eq_(response.status_code, status.HTTP_201_CREATED)
Aucun commentaire:
Enregistrer un commentaire