Why does mocking 'open' and returning a FileNotFoundError raise AttributeError: __exit__?
Why does mocking 'open' and returning a FileNotFoundError raise AttributeError: __exit__?
通过使用 FileNotFoundError
模拟 open
来测试 AttributeError: __exit__
。为什么会发生这种情况,我该如何解决?
以下代码打开一个简单的文本文件。如果文件丢失,它会生成一个默认值。它已由常规 运行 检查,似乎运行良好。
so_main.py
import os
import so_config
def load_savelocation():
path = os.path.join(so_config.ROOT, so_config.SAVELOCATION_FN)
savelocation_path = os.path.normpath(path)
try:
with open(savelocation_path) as f:
so_config.SAVELOCATION_PATH = f.readline()
except FileNotFoundError:
so_config.SAVELOCATION_PATH = so_config.ROOT
so_config.py
import os
ROOT, _ = os.path.split(__file__)
SAVELOCATION_PATH = None
SAVELOCATION_FN = 'savelocation.ini'
单元测试是另一回事。我在 so.main
中嘲笑了 open
命令。 test_so_main.py
有两个测试:一个用于正常打开存在的文件,第二个用于测试 FileNotFoundError
处理。
常规文件打开的第一次测试test_read_path_from_disk_file_into_config_py
工作正常。
第二个测试失败,因为 FileNotFoundError
引发了 AttributeError: __exit__
。
我可以将 self.mock_open.return_value
设置为 FileNotFoundError
或者我可以将其设置为 'garbage'
。这没有任何区别。
test_so_main.py
import unittest
import unittest.mock as mock
import so_config
import so_main
class TestReadSaveLocation(unittest.TestCase):
def setUp(self):
self.savelocation_path = so_config.SAVELOCATION_PATH
self.root = so_config.ROOT
so_config.ROOT = 'program root'
p = mock.patch('so_main.open')
self.mock_open = p.start()
self.addCleanup(p.stop)
def tearDown(self):
so_config.SAVELOCATION_PATH = self.savelocation_path
so_config.ROOT = self.root
def test_read_path_from_disk_file_into_config_py(self):
self.mock_open().__enter__().readline.return_value = 'data files location'
so_main.load_savelocation()
self.assertEqual('data files location', so_config.SAVELOCATION_PATH)
def test_missing_file_defaults_savelocation_to_program_root(self):
self.mock_open.return_value = FileNotFoundError
so_main.load_savelocation()
self.assertEqual('program root', so_config.SAVELOCATION_PATH)
我是 运行 Python 3.5.2 通过 PyCharm 2016.2.1 在 Windows 7 机器上。
您将函数模拟为 return 一个异常而不是 raise 它。
尝试使用 side_effect
(docs):
self.mock_open.side_effect = FileNotFoundError
通过使用 FileNotFoundError
模拟 open
来测试 AttributeError: __exit__
。为什么会发生这种情况,我该如何解决?
以下代码打开一个简单的文本文件。如果文件丢失,它会生成一个默认值。它已由常规 运行 检查,似乎运行良好。
so_main.py
import os
import so_config
def load_savelocation():
path = os.path.join(so_config.ROOT, so_config.SAVELOCATION_FN)
savelocation_path = os.path.normpath(path)
try:
with open(savelocation_path) as f:
so_config.SAVELOCATION_PATH = f.readline()
except FileNotFoundError:
so_config.SAVELOCATION_PATH = so_config.ROOT
so_config.py
import os
ROOT, _ = os.path.split(__file__)
SAVELOCATION_PATH = None
SAVELOCATION_FN = 'savelocation.ini'
单元测试是另一回事。我在 so.main
中嘲笑了 open
命令。 test_so_main.py
有两个测试:一个用于正常打开存在的文件,第二个用于测试 FileNotFoundError
处理。
常规文件打开的第一次测试test_read_path_from_disk_file_into_config_py
工作正常。
第二个测试失败,因为 FileNotFoundError
引发了 AttributeError: __exit__
。
我可以将 self.mock_open.return_value
设置为 FileNotFoundError
或者我可以将其设置为 'garbage'
。这没有任何区别。
test_so_main.py
import unittest
import unittest.mock as mock
import so_config
import so_main
class TestReadSaveLocation(unittest.TestCase):
def setUp(self):
self.savelocation_path = so_config.SAVELOCATION_PATH
self.root = so_config.ROOT
so_config.ROOT = 'program root'
p = mock.patch('so_main.open')
self.mock_open = p.start()
self.addCleanup(p.stop)
def tearDown(self):
so_config.SAVELOCATION_PATH = self.savelocation_path
so_config.ROOT = self.root
def test_read_path_from_disk_file_into_config_py(self):
self.mock_open().__enter__().readline.return_value = 'data files location'
so_main.load_savelocation()
self.assertEqual('data files location', so_config.SAVELOCATION_PATH)
def test_missing_file_defaults_savelocation_to_program_root(self):
self.mock_open.return_value = FileNotFoundError
so_main.load_savelocation()
self.assertEqual('program root', so_config.SAVELOCATION_PATH)
我是 运行 Python 3.5.2 通过 PyCharm 2016.2.1 在 Windows 7 机器上。
您将函数模拟为 return 一个异常而不是 raise 它。
尝试使用 side_effect
(docs):
self.mock_open.side_effect = FileNotFoundError