Search code examples
pythonpytestpatchpytest-mock

How to use patch for a variable in PyTest


I have below Python code:

#datamanager.py    

import os

BASE_DIR = '' #SOME_VALUE
data_list = '' #SOME_VALUE
loaded_data = dict.fromkeys(data_list)

def update_data():
    for key, current_model in loaded_data.items():
        mod_dir = os.path.join(BASE_DIR, key)
        if not os.path.exists(mod_dir):
            print("Model dir not present")
            continue
        model_files = os.listdir(mod_dir)
        if not model_files:
            print("Model dir is empty")
            continue

I am writing a pytest to test if mod_dir exist or not. I have to mock this as initially mod_dir will not be present. To do this, there is for loop which loop over loaded_data. I am trying to patch this variable but looks like this is not possible. I am trying to do something like below:

def test_update_models():
    mock_loaded_data = {'some_data': 'data_file'}
    with patch('datamanager.loaded_data', new=mock_loaded_data):
        update_data()

But I keep getting attribute error that loaded_data not found. I think it's not possible to patch the values of variables. What can I try next?


Solution

  • You might find that patch.object works here.

    However, if you are okay with editing the code under test, I'd recommend enabling the loaded data to be passed into the function (i.e. dependency injection):

    def update_data(data=None):
        if data is None:
            data = loaded_data
        for key, current_model in data.items():
            ...
    

    Then you can call update_data(mock_loaded_data) in your test, and the function has become a bit more flexible/reusable.