Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

py.test -- mock a constant and raise an exception in test function

I'm using py.test and mock. I have not been able to mock a constant. My test modifies the dict value that is assigned to the constant. This should raise an Exception in my test, but thus far it doesn't. I'm not sure what the problem is and would appreciate any help pinpointing the issue. Thank you.

the_module.py

MY_DICT = {'one': 1, 'two': 2, 'three': 3}                                        

class OneMissingException(Exception):                                             
    pass                                                                          

class Test1(object):                                                              
    def __init__(self):                                                           
        self.mydict = MY_DICT                                                     

    @property                                                                     
    def mydict(self):                                                             
        return self._mydict                                                       

    @mydict.setter                                                                
    def mydict(self, mydict):                                                     
        if 'one' not in mydict:                                                   
            raise OneMissingException                                             
        self._mydict = mydict 

test_themodule.py

import pytest                                                                                                                                                  
from unittest import mock                                                      
from the_module import Test1, OneMissingException                              

@pytest.fixture(scope='function')                                              
def my_dict():                                                                 
    return {'one': 1, 'two': 2, 'three': 3}                                    

def test_verify_test1_exception(my_dict):                                      
    my_dict.pop('one') # comment this out and test still passes                                                       
    with mock.patch("the_module.MY_DICT") as mydict:                           
        mydict.return_value.return_value = my_dict                             
        with pytest.raises(OneMissingException):                               
            Test1()  
like image 709
Dowwie Avatar asked Dec 15 '22 15:12

Dowwie


1 Answers

In your case you don't need mock (and you tried to use it in a wrong way, as nobody calls MY_DICT and you tried return_value)

use just pytest's monkeypatch fixture:

import pytest                                                                                                                                                  
from unittest import mock                                                      
from the_module import Test1, OneMissingException                              

@pytest.fixture                                              
def patched_my_dict(monkeypatch):                                                                 
    patched = {'one': 1, 'two': 2, 'three': 3}
    monkeypatch.setattr("the_module.MY_DICT", patched)
    return patched                                    

def test_verify_test1_exception(patched_my_dict):                                      
    patched_my_dict.pop('one') # comment this out and test will not pass                                                       
    with pytest.raises(OneMissingException):                               
        Test1()  
like image 108
Anatoly Bubenkov Avatar answered Dec 17 '22 05:12

Anatoly Bubenkov