2016-12-15 72 views
1

試圖讓Configparser.read使用模擬引發異常。mocking configparser.Configparser()。讀取以返回異常

# foo.py 
from six.moves import configparser 

def file1_formatted_correctly(): 
    try: 
     parser = configparser.ConfigParser() 
     parser.read(os.path.join("user/files/", 'configfile1')) 
    except configparser.Error: # I want to raise this in the unit test 
     return False 
    return True 

這是單元測試:

@mock.patch('foo.configparser.ConfigParser') 
def test_exception_raises(self, mocked_parser): 
    mock_parser.read.side_effect = configparser.Error("Error") 
    # I want to get the method to return True back 
    # by raising the configparser.Error exception 
    self.assertTrue(foo.file1_formatted_correctly()) 

但是,這似乎並沒有真正引發異常。

回答

0

有幾件事錯在這裏:

  • 名稱mocked_parser在argspec和測試mock_parser需要匹配
  • 測試邏輯是倒退 - 如果你想測試導致調用read提高那個錯誤,那麼測試中的斷言應該是assertFalse而不是assertTrue
  • 您還需要添加一個斷言模擬以確保讀取調用。

這些可能是小小的疏忽。主要問題有點微妙:

你嘲笑ConfigParser。你設置了閱讀副作用,但你已經在mock_parser.read.side_effect上設置了這個。在實際代碼中,readConfigParser().read上調用,而不是ConfigParser.read

I.e.你致電讀取ConfigParser()返回的對象。

>>> from mock import MagicMock 
>>> ConfigParser = MagicMock() 
>>> ConfigParser.read.side_effect = Exception('boom!') 
>>> ConfigParser().read.side_effect 
>>> ConfigParser.read.side_effect 
Exception('boom') 
>>> ConfigParser().read() 
<MagicMock name='mock().read()' id='30666832'> 
>>> ConfigParser.read() 
Exception: boom! 

所以,這是一種方式做正確

import mock 
import unittest 
import foo 
from six.moves import configparser 


mock_instance = mock.MagicMock() 
mock_instance.read.side_effect = configparser.Error('Boom!') 


class TheTest(unittest.TestCase): 

    @mock.patch('foo.configparser.ConfigParser', return_value=mock_instance) 
    def test_exception_raises(self, mocked_class): 
     self.assertFalse(foo.file1_formatted_correctly()) 
     mock_instance.read.assert_called_once_with('user/files/configfile1')