Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I replace a class variable for the duration of a single test in Python?

I'm trying to test a cache class where old items should be automatically deleted. The amount of items the cache can hold is controlled by a "constant" class variable like this:

class Cache(dict):
    MAX_ITEMS = 100

For testing purposes I would like to change that constant for the duration of a single test case. Using unittest.mock.patch I could replace the class variable with a MagicMock but that's not really what I'm trying to do. I just need to replace it with a different number.

Is there an elegant way to do this in Python (like patch), or should I just reset the variable myself on tearDown?


I'm using Python 3.4.3

like image 458
Hubro Avatar asked Aug 23 '15 18:08

Hubro


People also ask

Can you change class variable in Python?

We should be careful when changing the value of a class variable. If we try to change a class variable using an object, a new instance (or non-static) variable for that particular object is created and this variable shadows the class variables. Below is a Python program to demonstrate the same.

Can class variables be changed?

Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.

How do you change instance variables in Python?

We can modify the value of the instance variable and assign a new value to it using the object reference. Note: When you change the instance variable's values of one object, the changes will not be reflected in the remaining objects because every object maintains a separate copy of the instance variable.

How do you modify a class in Python?

Built-in classes can't be modified, but you can "hide" a built-in class (or any other of course) by one of the same name. Note that bare literals like 'ciao' and 23 will still belong to the real classes -- there's no way to change that; you'll need to use str('ciao') and int(23) to use the "fake" classes.


1 Answers

patch can do this already. try:

from unittest.mock import patch

class A:
    val = 1

assert A.val == 1
with patch.object(A, "val", "patched_value"):
    assert A.val == "patched_value"

assert A.val == 1

Of course you can use patch.object as a decorator as well.

like image 55
Dunes Avatar answered Oct 01 '22 13:10

Dunes