Given this example in Python 3.8, using Pydantic v2:
from pydantic import BaseModel
import pytest
from unittest.mock import MagicMock
class MyClass(BaseModel):
a: str = '123'
@pytest.fixture(name='myclass')
def fixture_myclass():
yield MagicMock(wraps=MyClass(), spec=MyClass)
def test_myclass_wraps(myclass):
assert myclass.a == '123'
Running this will raise:
AttributeError: Mock object has no attribute 'a'
I expect attribute access to pass through the wrapper here. However, since Pydantic doesn’t store attributes and methods normally, a
doesn’t exist in dir
or myclass.__dict__
. I think this is why the spec
doesn’t work the way I expect, since MagicMock
uses dir
under the hood to inspect the attributes on an object. So, it’s unable to spec the instance properly because of how Pydantic stores stuff.
So how can I mock a BaseModel
class? I would like to use spec
for test safety and wraps
for simplifying the amount of manual mocking.