Repository: Mityuha/fresh-bakery (language: python)

Issue:
Patch cakes with the Cake object only
Now it's possible to patch attributes this way (from the docs):
```python
async def test_example_3(bakery_mock: BakeryMock) -> None:
    bakery_mock.settings = lambda dsn: "any value"
    async with bakery_mock(MyBakery):
        assert MyBakery().settings == "any value"
```
As the practice show such a behaviour is an error prone and leads to confusion. 
There is a suggestion to get rid of any implicit behaviour in favour of explicit Cake objects' behaviour, like this
```python
async def test_example_3(bakery_mock: BakeryMock) -> None:
    bakery_mock.settings = Cake(lambda dsn: "any value")
    async with bakery_mock(MyBakery):
        assert MyBakery().settings == "any value"
```


Discussion / hints:

Fix patch:
diff --git a/pyproject.toml b/pyproject.toml
index 18cec60..4727209 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -33,7 +33,7 @@ profile = "black"
 
 [tool.poetry]
 name = "fresh-bakery"
-version = "0.3.5"
+version = "0.3.6"
 description = "Bake your dependencies stupidly simple!"
 readme = "README.md"
 license = "MIT"
@@ -166,7 +166,8 @@ deps =
     py{36,37}: pylint==2.13.9
     py{38,39,310,311,312}: pylint==3.1.0
 
-    pytest==7.0.1
+    py{36,37}: pytest==7.0.1
+    py{38,39,310,311,312}: pytest>=8.3.2
     pytest-mock==3.6.1
     typing_extensions==4.1.1
     pytest-trio==0.7.0
@@ -175,6 +176,7 @@ deps =
     py36: mypy==0.971
     py37: mypy==1.4.1
     py{38,39,310,311,312}: mypy==1.10.0
+
 commands = 
     black --check bakery/ tests/
     isort --check bakery tests/


Test patch:
diff --git a/bakery/testbakery.py b/bakery/testbakery.py
index 808aef0..c1b6377 100644
--- a/bakery/testbakery.py
+++ b/bakery/testbakery.py
@@ -1,4 +1,5 @@
 """Test bakery."""
+import warnings
 from inspect import Parameter, Signature
 from typing import Any, AsyncIterator, Dict, List, Optional, Type
 
@@ -7,6 +8,7 @@
 
 from . import Bakery as _Bakery
 from . import (
+    Cake,
     Cakeable,
     IngredientsProto,
     bake,
@@ -54,7 +56,7 @@ class BakeryMock:
 
     def __init__(self, mocker: MockerFixture):
         self._mocker_: MockerFixture = mocker
-        self._cake_mocks_: Dict[str, Any] = {}
+        self._cake_mocks_: Dict[str, Cakeable[Any]] = {}
         self._bakery_: Optional[Bakery] = None
         self._children_: List["BakeryMock"] = []
 
@@ -64,28 +66,24 @@ def __copy__(self) -> "BakeryMock":
         self._children_.append(mock_copy)
         return mock_copy
 
-    async def _patch_cake(self, *, bakery: Bakery, cake: Cakeable[Any], new_recipe: Any) -> None:
+    async def _patch_cake(
+        self, *, bakery: Bakery, cake: Cakeable[Any], new_recipe: Cakeable[Any]
+    ) -> None:
         """Patch cake recipe."""
         assert is_cake(cake)
+        assert is_cake(new_recipe)
         assert issubclass(bakery, _Bakery)
 
         ingredients: IngredientsProto = cake_ingredients(cake)
-        if is_cake(new_recipe):
-            new_cake: Cakeable[Any] = new_recipe
-            self._mocker_.patch.multiple(
-                ingredients,
-                recipe=cake_ingredients(new_cake).recipe,
-                recipe_args=cake_ingredients(new_cake).recipe_args,
-                recipe_kwargs=cake_ingredients(new_cake).recipe_kwargs,
-                cake_baking_method=cake_baking_method(new_cake),
-                result=await bake(new_cake),
-            )
-        else:
-            self._mocker_.patch.multiple(
-                ingredients,
-                recipe=new_recipe,
-                result=new_recipe,
-            )
+        new_cake: Cakeable[Any] = new_recipe
+        self._mocker_.patch.multiple(
+            ingredients,
+            recipe=cake_ingredients(new_cake).recipe,
+            recipe_args=cake_ingredients(new_cake).recipe_args,
+            recipe_kwargs=cake_ingredients(new_cake).recipe_kwargs,
+            cake_baking_method=cake_baking_method(new_cake),
+            result=await bake(new_cake),
+        )
 
     async def _patch(self, bakery: Bakery) -> None:
         """Start bakery `bakery` patching."""
@@ -143,6 +141,12 @@ def __setattr__(self, attr: str, value: Any) -> None:
         ):
             return super().__setattr__(attr, value)
 
+        if not is_cake(value):
+            warnings.warn(
+                "Direct value assignment to bakery_mock is deprecated and will be removed soon. "
+                "Please, use bakery_mock.attr = Cake(value) notation."
+            )
+            value = Cake(value)
         self._cake_mocks_[attr] = value
         return None
 
@@ -150,8 +154,7 @@ async def stopall(self) -> None:
         """Reset mocker and clear piece mocks."""
         await self.reset()
         for cake in self._cake_mocks_.values():
-            if is_cake(cake):
-                await unbake(cake)
+            await unbake(cake)
 
         for child in self._children_:
             await child.stopall()
diff --git a/docs/test_bakery.md b/docs/test_bakery.md
index 042e875..26aa7bb 100644
--- a/docs/test_bakery.md
+++ b/docs/test_bakery.md
@@ -34,12 +34,13 @@ class MyBakery(Bakery):
 
 
 # file test_example.py
+from bakery import Cake
 from bakery.testbakery import BakeryMock
 from example import MyBakery
 
 
 async def test_example_1(bakery_mock: BakeryMock) -> None:
-    bakery_mock.dsn = "fake dsn"  # <<< patch dsn
+    bakery_mock.dsn = Cake("fake dsn")  # <<< patch dsn
     async with bakery_mock(MyBakery):  # <<< mock against MyBakery
         assert MyBakery().dsn == "fake dsn"
         assert MyBakery().settings.dsn == "fake dsn"
@@ -57,63 +58,25 @@ You could also patch attributes **after** bakery was opened. But you should real
 
 
 async def test_example_2(bakery_mock: BakeryMock) -> None:
-    bakery: MyBakery = await MyBakery.aopen()  # open bakery anywhere
+    await MyBakery.aopen()  # open bakery anywhere
 
-    bakery_mock.dsn = "fake dsn"
+    bakery_mock.dsn = Cake("fake dsn")
     async with bakery_mock(MyBakery):
         assert MyBakery().dsn == "fake dsn"  # patched
         assert MyBakery().settings.dsn == "real dsn"  # not patched
 
-    await MyBakery.aclose()  # closed anywhere
+    await MyBakery.aclose()  # close anywhere
 ```
 Note that unlike the `test_example_1` example, in the `test_example_2` we patch `MyBakery` bakery after the bakery is opened. It means, that cake `settings` is already baked and its `.dsn` value is `"real dsn"`.
 
-## Patch the whole cake
-In the examples above we only patched the main part of the cake -- call it the recipe. The recipe is the object by which the baking method is determined. 
-
-!!! info
-    In other words the recipe is the first argument passed to Cake. For example, the cake `Cake(1)` has the recipe `1`. The cake `Cake(list, (1,2,3))` has the recipe `list` and so forth.
-
-So, if you will patch the recipe with another recipe, that incompatible with the rest of cake's argument, you will get an error:
-```python
-# file test_example.py
-
-
-async def test_example_with_error(bakery_mock: BakeryMock) -> None:
-    bakery_mock.settings = 1
-    # TypeError: 'int' object is not callable
-    # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
-    async with bakery_mock(MyBakery):
-        pass
-```
-You could patch `settings` with lambda function, with `dsn` parameter and any return value:
-```python
-# file test_example.py
-
-
-async def test_example_3(bakery_mock: BakeryMock) -> None:
-    bakery_mock.settings = lambda dsn: "any value"
-    async with bakery_mock(MyBakery):
-        assert MyBakery().settings == "any value"
-```
-
-You could also patch the whole cake: just assign the cake object to corresponding `bakery_mock` attribute:
-```python
-# file test_example.py
-
-
-async def test_example_4(bakery_mock: BakeryMock) -> None:
-    bakery_mock.settings = Cake(1)
-    async with bakery_mock(MyBakery):
-        assert MyBakery().settings == 1
-```
+## Patch hand made cakes
 Hand made cakes are also supported:
 ```python
 # file test_example.py
 from bakery import hand_made, BakingMethod
 
 
-async def test_example_5(bakery_mock: BakeryMock) -> None:
+async def test_example_3(bakery_mock: BakeryMock) -> None:
     bakery_mock.settings = hand_made(
         Cake(list),
         cake_baking_method=BakingMethod.BAKE_NO_BAKE,
diff --git a/tests/bakery_mock/__init__.py b/tests/bakery_mock/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/bakery_mock/test_complex_bakery_mock.py b/tests/bakery_mock/test_complex_bakery_mock.py
new file mode 100644
index 0000000..d76986f
--- /dev/null
+++ b/tests/bakery_mock/test_complex_bakery_mock.py
@@ -0,0 +1,107 @@
+from dataclasses import dataclass
+from typing import Dict, List
+
+from bakery import Bakery, Cake, is_baked
+from bakery.testbakery import BakeryMock
+
+
+async def test_complex_bakery_mock1(bakery_mock: BakeryMock) -> None:
+    @dataclass
+    class CPU:
+        core_num: int
+        manufacturer: str
+
+    class MyPC:
+        def __init__(self, *cpus: CPU):
+            self.cpus = cpus
+
+    class Comp(Bakery):
+        core_num: int = Cake(4)
+        manufacturer: str = Cake("Intel")
+        cpu1: CPU = Cake(CPU, core_num=core_num, manufacturer=manufacturer)
+        mypc: MyPC = Cake(MyPC, cpu1)
+
+    bakery_mock.core_num = Cake(8)
+    bakery_mock.manufacturer = Cake("AMD")
+
+    await bakery_mock.patch(Comp)
+
+    async with Comp() as my_pc:
+        assert my_pc.mypc.cpus[0].core_num == 8
+        assert Comp.mypc.cpus[0].core_num() == 8
+        assert Comp().mypc.cpus[0].core_num == 8
+        assert my_pc.mypc.cpus[0].manufacturer == "AMD"
+        assert Comp.mypc.cpus[0].manufacturer() == "AMD"
+        assert Comp.mypc.cpus[0]().manufacturer == "AMD"
+        assert Comp.mypc.cpus()[0].manufacturer == "AMD"
+        assert Comp.mypc().cpus[0].manufacturer == "AMD"
+        assert Comp().mypc.cpus[0].manufacturer == "AMD"
+
+        await bakery_mock.reset()
+
+    async with Comp() as my_pc:
+        assert my_pc.core_num == 4
+        assert Comp.core_num() == 4
+        assert Comp().core_num == 4
+        assert my_pc.mypc.cpus[0].manufacturer == "Intel"
+        assert Comp.mypc.cpus[0].manufacturer() == "Intel"
+        assert Comp.mypc.cpus[0]().manufacturer == "Intel"
+        assert Comp.mypc.cpus()[0].manufacturer == "Intel"
+        assert Comp.mypc().cpus[0].manufacturer == "Intel"
+        assert Comp().mypc.cpus[0].manufacturer == "Intel"
+
+        assert my_pc.mypc.cpus[0].core_num == 4
+        assert Comp.mypc.cpus[0].core_num() == 4
+        assert Comp().mypc.cpus[0].core_num == 4
+        assert my_pc.mypc.cpus[0].manufacturer == "Intel"
+        assert Comp.mypc.cpus[0].manufacturer() == "Intel"
+        assert Comp.mypc.cpus()[0].manufacturer == "Intel"
+        assert Comp().core_num == 4
+        assert Comp().manufacturer == "Intel"
+
+
+async def test_complex_bakery_mock2(bakery_mock: BakeryMock) -> None:
+    @dataclass
+    class Settings:
+        postgres_dsn: str
+        some_list: List[str]
+        some_dict: Dict[str, str]
+
+    @dataclass
+    class Manager:
+        postgres_dsn: str
+        item_0: str
+        key_value: str
+
+    class MyBakery(Bakery):
+        settings: Settings = Cake(
+            Settings,
+            postgres_dsn="some dsn",
+            some_list=["item0", "item_1"],
+            some_dict={"key": "value"},
+        )
+        manager: Manager = Cake(
+            Manager,
+            postgres_dsn=settings.postgres_dsn,
+            item_0=settings.some_list[0],
+            key_value=settings.some_dict["key"],
+        )
+
+    postgres_dsn_mock: str = "mock"
+    some_list_mock: List[str] = ["mock0", "mock1"]
+    some_dict_mock: Dict[str, str] = {"key": "mock"}
+
+    new_settings = Cake(
+        Settings,
+        postgres_dsn=postgres_dsn_mock,
+        some_list=some_list_mock,
+        some_dict=some_dict_mock,
+    )
+    bakery_mock.settings = new_settings
+
+    async with bakery_mock(MyBakery):
+        assert MyBakery().manager.postgres_dsn == postgres_dsn_mock
+        assert MyBakery().manager.item_0 == some_list_mock[0]
+        assert MyBakery().manager.key_value == some_dict_mock["key"]
+        assert is_baked(new_settings)  # type: ignore
+        assert MyBakery().settings == new_settings()  # type: ignore
diff --git a/tests/bakery_mock/test_deprecated_direct_assignment.py b/tests/bakery_mock/test_deprecated_direct_assignment.py
new file mode 100644
index 0000000..69cd77a
--- /dev/null
+++ b/tests/bakery_mock/test_deprecated_direct_assignment.py
@@ -0,0 +1,43 @@
+from time import sleep
+
+from bakery import Bakery, Cake, is_cake
+from bakery.testbakery import BakeryMock
+
+
+async def test_bakery_mock_replace_recipe(bakery_mock: BakeryMock) -> None:
+    """Test recipe replacement."""
+
+    def sleeper(sleep_for: float) -> float:
+        """Simply sleep."""
+        sleep(sleep_for)
+        return sleep_for
+
+    class Comp(Bakery):
+        """Comp."""
+
+        sleeper1: float = Cake(sleeper, 100)
+        sleeper2: float = Cake(sleeper, 200)
+        some_list: list = Cake([1, 2, Cake(sleeper, 300)])
+        total: float = Cake(sum, (sleeper1, sleeper2, some_list[2]))  # type: ignore
+
+    class Comp2(Bakery):
+        """Comp2."""
+
+        comp: Comp = Cake(Comp())
+
+    bakery_mock.sleeper1 = lambda *_args: 100
+    bakery_mock.sleeper2 = lambda *_args: 200
+    bakery_mock.some_list = [1, 2, 300]
+    assert all(is_cake(v) for v in getattr(bakery_mock, "_cake_mocks_").values())
+
+    async with bakery_mock(Comp):
+        assert Comp().sleeper1 == 100
+        assert Comp().sleeper2 == 200
+        assert Comp().some_list[2] == 300
+        assert Comp().total == 600
+
+    async with bakery_mock(Comp), Comp2():
+        assert Comp2().comp.sleeper1 == 100
+        assert Comp2().comp.sleeper2 == 200
+        assert Comp2().comp.some_list[2] == 300
+        assert Comp2().comp.total == 600
diff --git a/tests/bakery_mock/test_docs_examples.py b/tests/bakery_mock/test_docs_examples.py
new file mode 100644
index 0000000..037b245
--- /dev/null
+++ b/tests/bakery_mock/test_docs_examples.py
@@ -0,0 +1,41 @@
+from dataclasses import dataclass
+
+from bakery import Bakery, BakingMethod, Cake, hand_made
+from bakery.testbakery import BakeryMock
+
+
+@dataclass
+class Settings:
+    dsn: str
+
+
+class MyBakery(Bakery):
+    dsn: str = Cake("real dsn")
+    settings: Settings = Cake(Settings, dsn=dsn)
+
+
+async def test_example_1(bakery_mock: BakeryMock) -> None:
+    bakery_mock.dsn = Cake("fake dsn")  # <<< patch dsn
+    async with bakery_mock(MyBakery):  # <<< mock against MyBakery
+        assert MyBakery().dsn == "fake dsn"
+        assert MyBakery().settings.dsn == "fake dsn"
+
+
+async def test_example_2(bakery_mock: BakeryMock) -> None:
+    await MyBakery.aopen()  # open bakery anywhere
+
+    bakery_mock.dsn = Cake("fake dsn")
+    async with bakery_mock(MyBakery):
+        assert MyBakery().dsn == "fake dsn"  # patched
+        assert MyBakery().settings.dsn == "real dsn"  # not patched
+
+    await MyBakery.aclose()  # closed anywhere
+
+
+async def test_example_3(bakery_mock: BakeryMock) -> None:
+    bakery_mock.settings = hand_made(
+        Cake(list),
+        cake_baking_method=BakingMethod.BAKE_NO_BAKE,
+    )
+    async with bakery_mock(MyBakery):
+        assert MyBakery().settings is list
diff --git a/tests/bakery_mock/test_mock_after_open.py b/tests/bakery_mock/test_mock_after_open.py
new file mode 100644
index 0000000..8725ba9
--- /dev/null
+++ b/tests/bakery_mock/test_mock_after_open.py
@@ -0,0 +1,34 @@
+from bakery import Bakery, Cake
+from bakery.testbakery import BakeryMock
+
+
+async def test_mock_after_open(bakery_mock: BakeryMock) -> None:
+    class MyPC(Bakery):
+
+        core_num: int = Cake(4)
+        manufacturer: str = Cake("Intel")
+
+    bakery_mock.core_num, bakery_mock.manufacturer = Cake(5), Cake("AMD")
+
+    async with MyPC() as my_pc:
+        assert my_pc.core_num == 4
+        assert MyPC.core_num() == 4
+        assert MyPC().core_num == 4
+        assert my_pc.manufacturer == "Intel"
+        assert MyPC.manufacturer() == "Intel"
+        assert MyPC().manufacturer == "Intel"
+
+        async with bakery_mock(MyPC):
+            assert my_pc.core_num == 5
+            assert MyPC.core_num() == 5
+            assert MyPC().core_num == 5
+            assert my_pc.manufacturer == "AMD"
+            assert MyPC.manufacturer() == "AMD"
+            assert MyPC().manufacturer == "AMD"
+
+        assert my_pc.core_num == 4
+        assert MyPC.core_num() == 4
+        assert MyPC().core_num == 4
+        assert my_pc.manufacturer == "Intel"
+        assert MyPC.manufacturer() == "Intel"
+        assert MyPC().manufacturer == "Intel"
diff --git a/tests/bakery_mock/test_nested_cakes.py b/tests/bakery_mock/test_nested_cakes.py
new file mode 100644
index 0000000..dd52c4e
--- /dev/null
+++ b/tests/bakery_mock/test_nested_cakes.py
@@ -0,0 +1,56 @@
+from typing import Any, List
+
+from bakery import Bakery, Cake
+from bakery.testbakery import BakeryMock
+
+
+async def test_nested_cakes_mock_simple(bakery_mock: BakeryMock) -> None:
+    def make_list(*args: Any) -> List:
+        return list(*args)
+
+    class MyBakery(Bakery):
+        value: float = Cake(
+            sum,  # type: ignore
+            Cake(
+                Cake(
+                    make_list,  # type: ignore
+                    [Cake(sum, [1, 2, 3])],  # type: ignore
+                ),
+            ),
+        )
+
+    async with MyBakery() as bakery:
+        assert bakery.value == 6
+
+    bakery_mock.value = Cake(10)
+    async with bakery_mock(MyBakery):
+        assert MyBakery().value == 10
+
+    bakery_mock.value = Cake(sum, Cake(make_list, (1, 2, 3, 4)))  # type: ignore
+    async with bakery_mock(MyBakery):
+        assert MyBakery().value == 10
+
+
+async def test_nested_cakes_mock_complex(bakery_mock: BakeryMock) -> None:
+    class Database:
+        def __init__(self, table: str):
+            self.connected: bool = False
+            self.table: str = table
+
+        async def __aenter__(self) -> "Database":
+            self.connected = True
+            return self
+
+        async def __aexit__(self, *_args: Any) -> None:
+            self.connected = False
+
+    class MyBakery(Bakery):
+        database: Database = Cake(Cake(Database, table=Cake("table")))
+
+    async with MyBakery() as bakery:
+        assert bakery.database.connected
+
+    bakery_mock.database = Cake(None)
+
+    async with bakery_mock(MyBakery):
+        assert MyBakery().database is None
diff --git a/tests/bakery_mock/test_patch_before_open.py b/tests/bakery_mock/test_patch_before_open.py
new file mode 100644
index 0000000..377046d
--- /dev/null
+++ b/tests/bakery_mock/test_patch_before_open.py
@@ -0,0 +1,32 @@
+from bakery import Bakery, Cake
+from bakery.testbakery import BakeryMock
+
+
+async def test_bakery_patch_before_open(bakery_mock: BakeryMock) -> None:
+    class MyPC(Bakery):
+
+        core_num: int = Cake(4)
+        manufacturer: str = Cake("Intel")
+
+    bakery_mock.core_num = Cake(6)
+    bakery_mock.manufacturer = Cake("AMD")
+
+    await bakery_mock.patch(MyPC)
+
+    async with MyPC() as my_pc:
+        assert my_pc.core_num == 6
+        assert MyPC.core_num() == 6
+        assert MyPC().core_num == 6
+        assert my_pc.manufacturer == "AMD"
+        assert MyPC.manufacturer() == "AMD"
+        assert MyPC().manufacturer == "AMD"
+
+    await bakery_mock.reset()
+
+    async with MyPC() as my_pc:
+        assert my_pc.core_num == 4
+        assert MyPC.core_num() == 4
+        assert MyPC().core_num == 4
+        assert my_pc.manufacturer == "Intel"
+        assert MyPC.manufacturer() == "Intel"
+        assert MyPC().manufacturer == "Intel"
diff --git a/tests/test_bakery_mock.py b/tests/test_bakery_mock.py
deleted file mode 100644
index 6de865a..0000000
--- a/tests/test_bakery_mock.py
+++ /dev/null
@@ -1,296 +0,0 @@
-"""Test bakery mock."""
-
-
-from dataclasses import dataclass
-from time import sleep
-from typing import Any, Dict, List
-
-from bakery import Bakery, Cake, is_baked
-from bakery.testbakery import BakeryMock
-
-
-async def test_bakery_mock1(bakery_mock: BakeryMock) -> None:
-    """Test bakery mock."""
-
-    class MyPC(Bakery):
-        """My bakery."""
-
-        core_num: int = Cake(4)
-        manufacturer: str = Cake("Intel")
-
-    bakery_mock.core_num, bakery_mock.manufacturer = 5, "AMD"
-
-    async with MyPC() as my_pc:
-        assert my_pc.core_num == 4
-        assert MyPC.core_num() == 4
-        assert MyPC().core_num == 4
-        assert my_pc.manufacturer == "Intel"
-        assert MyPC.manufacturer() == "Intel"
-        assert MyPC().manufacturer == "Intel"
-
-        async with bakery_mock(MyPC):
-            assert my_pc.core_num == 5
-            assert MyPC.core_num() == 5
-            assert MyPC().core_num == 5
-            assert my_pc.manufacturer == "AMD"
-            assert MyPC.manufacturer() == "AMD"
-            assert MyPC().manufacturer == "AMD"
-
-        assert my_pc.core_num == 4
-        assert MyPC.core_num() == 4
-        assert MyPC().core_num == 4
-        assert my_pc.manufacturer == "Intel"
-        assert MyPC.manufacturer() == "Intel"
-        assert MyPC().manufacturer == "Intel"
-
-
-async def test_bakery_patch_before_open(bakery_mock: BakeryMock) -> None:
-    """Test bakery patch before open."""
-
-    class MyPC(Bakery):
-        """My bakery."""
-
-        core_num: int = Cake(4)
-        manufacturer: str = Cake("Intel")
-
-    bakery_mock.core_num = Cake(6)
-    bakery_mock.manufacturer = "AMD"
-
-    await bakery_mock.patch(MyPC)
-
-    async with MyPC() as my_pc:
-        assert my_pc.core_num == 6
-        assert MyPC.core_num() == 6
-        assert MyPC().core_num == 6
-        assert my_pc.manufacturer == "AMD"
-        assert MyPC.manufacturer() == "AMD"
-        assert MyPC().manufacturer == "AMD"
-
-    await bakery_mock.reset()
-
-    async with MyPC() as my_pc:
-        assert my_pc.core_num == 4
-        assert MyPC.core_num() == 4
-        assert MyPC().core_num == 4
-        assert my_pc.manufacturer == "Intel"
-        assert MyPC.manufacturer() == "Intel"
-        assert MyPC().manufacturer == "Intel"
-
-
-async def test_complex_bakery_mock1(bakery_mock: BakeryMock) -> None:
-    """Test bakery mock complex enough."""
-
-    @dataclass
-    class CPU:
-        """Cpu."""
-
-        core_num: int
-        manufacturer: str
-
-    class MyPC:
-        """My pc."""
-
-        def __init__(self, *cpus: CPU):
-            self.cpus = cpus
-
-    class Comp(Bakery):
-        """Bakery."""
-
-        core_num: int = Cake(4)
-        manufacturer: str = Cake("Intel")
-        cpu1: CPU = Cake(CPU, core_num=core_num, manufacturer=manufacturer)
-        mypc: MyPC = Cake(MyPC, cpu1)
-
-    bakery_mock.core_num = 8
-    bakery_mock.manufacturer = "AMD"
-
-    await bakery_mock.patch(Comp)
-
-    async with Comp() as my_pc:
-        assert my_pc.mypc.cpus[0].core_num == 8
-        assert Comp.mypc.cpus[0].core_num() == 8
-        assert Comp().mypc.cpus[0].core_num == 8
-        assert my_pc.mypc.cpus[0].manufacturer == "AMD"
-        assert Comp.mypc.cpus[0].manufacturer() == "AMD"
-        assert Comp.mypc.cpus[0]().manufacturer == "AMD"
-        assert Comp.mypc.cpus()[0].manufacturer == "AMD"
-        assert Comp.mypc().cpus[0].manufacturer == "AMD"
-        assert Comp().mypc.cpus[0].manufacturer == "AMD"
-
-        await bakery_mock.reset()
-
-    async with Comp() as my_pc:
-        assert my_pc.core_num == 4
-        assert Comp.core_num() == 4
-        assert Comp().core_num == 4
-        assert my_pc.mypc.cpus[0].manufacturer == "Intel"
-        assert Comp.mypc.cpus[0].manufacturer() == "Intel"
-        assert Comp.mypc.cpus[0]().manufacturer == "Intel"
-        assert Comp.mypc.cpus()[0].manufacturer == "Intel"
-        assert Comp.mypc().cpus[0].manufacturer == "Intel"
-        assert Comp().mypc.cpus[0].manufacturer == "Intel"
-
-        assert my_pc.mypc.cpus[0].core_num == 4
-        assert Comp.mypc.cpus[0].core_num() == 4
-        assert Comp().mypc.cpus[0].core_num == 4
-        assert my_pc.mypc.cpus[0].manufacturer == "Intel"
-        assert Comp.mypc.cpus[0].manufacturer() == "Intel"
-        assert Comp.mypc.cpus()[0].manufacturer == "Intel"
-        assert Comp().core_num == 4
-        assert Comp().manufacturer == "Intel"
-
-
-async def test_complex_bakery_mock2(bakery_mock: BakeryMock) -> None:
-    """Test bakery mock."""
-
-    @dataclass
-    class Settings:
-        """Some settings."""
-
-        postgres_dsn: str
-        some_list: List[str]
-        some_dict: Dict[str, str]
-
-    @dataclass
-    class Manager:
-        """Some manager."""
-
-        postgres_dsn: str
-        item_0: str
-        key_value: str
-
-    class MyBakery(Bakery):
-        """My bakery."""
-
-        settings: Settings = Cake(
-            Settings,
-            postgres_dsn="some dsn",
-            some_list=["item0", "item_1"],
-            some_dict={"key": "value"},
-        )
-        manager: Manager = Cake(
-            Manager,
-            postgres_dsn=settings.postgres_dsn,
-            item_0=settings.some_list[0],
-            key_value=settings.some_dict["key"],
-        )
-
-    postgres_dsn_mock: str = "mock"
-    some_list_mock: List[str] = ["mock0", "mock1"]
-    some_dict_mock: Dict[str, str] = {"key": "mock"}
-
-    new_settings = Cake(
-        Settings,
-        postgres_dsn=postgres_dsn_mock,
-        some_list=some_list_mock,
-        some_dict=some_dict_mock,
-    )
-    bakery_mock.settings = new_settings
-
-    async with bakery_mock(MyBakery):
-        assert MyBakery().manager.postgres_dsn == postgres_dsn_mock
-        assert MyBakery().manager.item_0 == some_list_mock[0]
-        assert MyBakery().manager.key_value == some_dict_mock["key"]
-        assert is_baked(new_settings)  # type: ignore
-        assert MyBakery().settings == new_settings()  # type: ignore
-
-
-async def test_bakery_mock_replace_recipe(bakery_mock: BakeryMock) -> None:
-    """Test recipe replacement."""
-
-    def sleeper(sleep_for: float) -> float:
-        """Simply sleep."""
-        sleep(sleep_for)
-        return sleep_for
-
-    class Comp(Bakery):
-        """Comp."""
-
-        sleeper1: float = Cake(sleeper, 100)
-        sleeper2: float = Cake(sleeper, 200)
-        some_list: list = Cake([1, 2, Cake(sleeper, 300)])
-        total: float = Cake(sum, (sleeper1, sleeper2, some_list[2]))  # type: ignore
-
-    class Comp2(Bakery):
-        """Comp2."""
-
-        comp: Comp = Cake(Comp())
-
-    bakery_mock.sleeper1 = lambda *_args: 100
-    bakery_mock.sleeper2 = lambda *_args: 200
-    bakery_mock.some_list = [1, 2, 300]
-
-    async with bakery_mock(Comp):
-        assert Comp().sleeper1 == 100
-        assert Comp().sleeper2 == 200
-        assert Comp().some_list[2] == 300
-        assert Comp().total == 600
-
-    async with bakery_mock(Comp), Comp2():
-        assert Comp2().comp.sleeper1 == 100
-        assert Comp2().comp.sleeper2 == 200
-        assert Comp2().comp.some_list[2] == 300
-        assert Comp2().comp.total == 600
-
-
-async def test_nested_cakes_mock_simple(bakery_mock: BakeryMock) -> None:
-    """Test simple nested cakes mock."""
-
-    def make_list(*args: Any) -> List:
-        """Make list."""
-        return list(*args)
-
-    class MyBakery(Bakery):
-        """MyBakery."""
-
-        value: float = Cake(
-            sum,  # type: ignore
-            Cake(
-                Cake(
-                    make_list,  # type: ignore
-                    [Cake(sum, [1, 2, 3])],  # type: ignore
-                ),
-            ),
-        )
-
-    async with MyBakery() as bakery:
-        assert bakery.value == 6
-
-    bakery_mock.value = Cake(10)
-    async with bakery_mock(MyBakery):
-        assert MyBakery().value == 10
-
-    bakery_mock.value = lambda *args: sum(*args, 4)  # type: ignore
-    async with bakery_mock(MyBakery):
-        assert MyBakery().value == 10
-
-
-async def test_nested_cakes_mock(bakery_mock: BakeryMock) -> None:
-    """Test nested cakes mock."""
-
-    class Database:
-        """Database."""
-
-        def __init__(self, table: str):
-            self.connected: bool = False
-            self.table: str = table
-
-        async def __aenter__(self) -> "Database":
-            self.connected = True
-            return self
-
-        async def __aexit__(self, *_args: Any) -> None:
-            self.connected = False
-
-    class MyBakery(Bakery):
-        """MyBakery."""
-
-        database: Database = Cake(Cake(Database, table=Cake("table")))
-
-    async with MyBakery() as bakery:
-        assert bakery.database.connected
-
-    bakery_mock.database = Cake(None)
-
-    async with bakery_mock(MyBakery):
-        assert MyBakery().database is None