J
J
Jungles2020-08-27 18:26:12
Python
Jungles, 2020-08-27 18:26:12

How does unittest work?

program code

spoiler
import requests


class Asteroid():
    BASE_API_URL = 'http://www.neowsapp.com/rest/v1/neo/{}?api_key=DEMO_KEY'

    def __init__(self,spk_id):
        self.api_url = self.BASE_API_URL.format(spk_id)

    def get_data(self):
        return requests.get(self.api_url).json()

    @property
    def name(self):
        return self.get_data()['name']

    @property
    def diameter(self):
        return float(self.get_data()['estimated_diameter']['meters']['estimated\
_diameter_max'])


test code
spoiler
import json
import unittest
from unittest.mock import patch

from asteroid import Asteroid


class TestAsteroid(unittest.TestCase):

    def setUp(self):
        self.asteroid = Asteroid(3726710)
    #в случае, если интернета нет, возвращаются данные из текстового файла, с тем же содержимым, которое возвращает API
    
    def mocked_get_data(self):
        with open('asteroid_info.txt', 'r') as f:
            return json.loads(f.read())
        

    @patch('asteroid.Asteroid.get_data' , mocked_get_data)
    def test_name(self):
        self.assertEqual(
            self.asteroid.name, '(2015 RC)')

    @patch('asteroid.Asteroid.get_data' , mocked_get_data)
    def test_diameter(self):
        self.assertEqual(self.asteroid.diameter, 82.0427064882)
    

if __name__ == '__main__':
    unittest.main()


Question about the method after the comment.
how the data from a file is transferred self.name and self.diameter?
I guess here
@patch('asteroid.Asteroid.get_data' , mocked_get_data)

But it is interesting how it is implemented

That is, if the method did not exist.
We would catch an error, 1) about the HTTP request break, and therefore the absence of self.name and self.diameter

But somehow we switch to the data from the file and read from there. But how does it happen?
maybe the value changes somehow, for example,
def mocked_get_data(self):
        with open('asteroid_info.txt', 'r') as f:
            data =  json.loads(f.read())
            # неявно self.asteroid.name = data['name']

or in some other way?

PS: blitz question.

Why Executes quietly, but a.name output a list from ConnectionError , 1) why this error was not raised with a = Asteroid(32241432) 2) why a NameError was not raised with a.name
a = Asteroid(32241432)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Kuts, 2020-08-27
@Jungles

@patch('asteroid.Asteroid.get_data' , mocked_get_data)

In the test, the get_data method of the Asteroid class of the asteroid module is replaced by the output of the mocked_get_data function, which simply displays the contents of the asteroid_info.txt file, simulating an external API request.
If this patch did not exist, then the real API would twitch
Why
a = Asteroid(32241432)
Runs quietly

because there is an ordinary assignment
def __init__(self,spk_id):
        self.api_url = self.BASE_API_URL.format(spk_id)

and here a.name output the list from ConnectionError ,

Because when name is called, requests.get(self.api_url) is called, which pulls the external api. And if it doesn't respond, it throws a ConnectionError

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question