I'm attempting to use freezegun in my unit tests to patch a field in a dataclass that is set to the current date when the object is initialised. I would imagine the question is relevant to any attempt to patch a function being used as a default_factory outside of just freezegun. The dataclass is frozen so its immutable.
For example if my dataclass is:
@dataclass(frozen=True)
class MyClass:
name: str
timestamp: datetime.datetime = field(init=False, default_factory=datetime.datetime.now)
When I patch datetime with freezegun, it has no impact on the initialisation of the timestamp in MyClass (it still sets timestamp to the current date returned by now() in the unit test, causing the test to fail).
I'm assuming it has to do with the default factory and module being loaded well before the patch is in place. I have tried patching datetime, and then reloading the module with importlib.reload but with no luck.
The solution I have at the moment is:
@dataclass(frozen=True)
class MyClass:
name: str
timestamp: datetime.datetime = field(init=False)
def __post_init__(self):
object.__setattr__(self, "timestamp", datetime.datetime.now())
which works.
Ideally though, I would like a non-invasive solution that doesn't require me changing my production code to enable my unit tests.