Перейти до змісту

EXAMPLES parametrize, fixture and mock

Основний код:

import datetime


def outdated_products(products: list) -> list:
    return [product["name"] for product in products
            if product["expiration_date"] < datetime.date.today()]

Тести:

from datetime import date
from unittest import mock
from unittest.mock import MagicMock

import pytest

from app.main import outdated_products


class TestOutdatedProducts:

    @pytest.fixture()
    def outdated_products_fixture(self) -> None:
        list_of_products_dicts = [
            {
                "name": "salmon",
                "expiration_date": date(2022, 2, 10),
                "price": 600
            },
            {
                "name": "chicken",
                "expiration_date": date(2022, 2, 5),
                "price": 120
            },
            {
                "name": "duck",
                "expiration_date": date(2022, 2, 1),
                "price": 160
            }
        ]
        return list_of_products_dicts

    @pytest.mark.parametrize(
        "today_date,expected_outdated_products",
        [
            pytest.param(
                date(2022, 2, 1),
                [],
                id="No expired products by this day"
            ),
            pytest.param(
                date(2022, 2, 2),
                ["duck"],
                id="Have expired product by this day"
            ),
            pytest.param(
                date(2022, 2, 6),
                ["chicken", "duck"],
                id="Have expired product by this day"
            ),
            pytest.param(
                date(2022, 2, 9),
                ["chicken", "duck"],
                id="Have expired product by this day"
            ),
            pytest.param(
                date(2022, 2, 11),
                ["salmon", "chicken", "duck"],
                id="Have expired product by this day"
            )
        ]
    )
    @mock.patch("app.main.datetime.date")
    def test_outdated_products(self,
                               mocked_date_function: MagicMock,
                               today_date: date,
                               expected_outdated_products: list,
                               outdated_products_fixture: list[dict]
                               ) -> None:

        mocked_date_function.today.return_value = today_date
        assert outdated_products(outdated_products_fixture) == expected_outdated_products

P.S. Після @mock.patch в def test_outdated_products перший (після self) параметр ОБОВ'ЯЗКОВО повинен бути ім'ям замоканої функції!!!! Потім параметри з parametrize, і останні — fixtures

ПРИКЛАД 2 (mock.patch, mark.parametrize, pytest.param):

Основний код:

import datetime
import requests


def valid_google_url(url: str) -> bool:
    response = requests.get(url)
    return True if response.status_code == 200 else False


def has_internet_connection() -> bool:
    current_time = datetime.datetime.now()
    return True if current_time.hour in range(6, 23) else False


def can_access_google_page(url: str) -> str:
    if has_internet_connection() and valid_google_url(url):
        return "Accessible"
    else:
        return "Not accessible"

Тести:

from unittest import mock
from unittest.mock import MagicMock

from app.main import can_access_google_page

import pytest


class TestCanAccessGooglePage:
    @pytest.mark.parametrize(
        "input_url,url_is_valid,has_internet,expected_result",
        [
            (
                "https://anyurl.com/",
                True,
                True,
                "Accessible"
            ),
            (
                "https://anyurl.com/",
                False,
                True,
                "Not accessible"
            ),
            (
                "https://anyurl.com/",
                True,
                False,
                "Not accessible"
            ),
            (
                "https://anyurl.com/",
                False,
                False,
                "Not accessible"
            )
        ],
        ids=[
            "Accessible when url is valid \
and Internet connection exists",
            "Not accessible when url is invalid \
and Internet connection exists",
            "Not accessible when url is valid \
and Internet connection does not exist",
            "Test when url is not valid and \
Internet connection does not exist"
        ]
    )
    @mock.patch("app.main.valid_google_url")
    @mock.patch("app.main.has_internet_connection")
    def test_can_access_google_paged(self,
                                     mocked_valid_google_url: MagicMock,
                                     mocked_has_internet: MagicMock,
                                     input_url: str,
                                     url_is_valid: bool,
                                     has_internet: bool,
                                     expected_result: str) -> None:
        mocked_valid_google_url.return_value = url_is_valid
        mocked_has_internet.return_value = has_internet
        assert can_access_google_page(input_url) == expected_result