我正在使用datashape Python包并使用@datashape.discover.register
装饰器注册新类型。我想测试当我在我正在注册的类型的对象上调用datashape.discover
时,它会调用正在修饰的函数。我也喜欢用良好的单元测试原理来做这件事,这意味着没有实际执行被装饰的功能,因为它会产生我不想要的副作用。但是,这不起作用。
以下是一些示例代码来说明问题:
myfile.py:
@datashape.discover.register(SomeType)
def discover_some_type(data)
...some stuff i don't want done in a unit test...
test_myfile.py:
class TestDiscoverSomeType(unittest.TestCase):
@patch('myfile.discover_some_type')
def test_discover_some_type(self, mock_discover_some_type):
file_to_discover = SomeType()
datashape.discover(file_to_discover)
mock_discover_some_type.assert_called_with(file_to_discover)
问题似乎是我想要模拟的函数在测试体中被嘲笑,但是,当它被装饰时(即它被导入时)它没有被嘲笑。 discover.register
函数基本上在内部注册要修饰的函数,以便在使用给定类型的参数调用discover()
时查找它。不幸的是,它似乎每次都在内部注册真正的函数,而不是我想要的修补版本,所以它总是会调用真正的函数。
有关如何修补正在修饰的函数的任何想法,并声明在调用datashape.discover
时调用它?
答案 0 :(得分:1)
这是我发现的解决方案,只有一点点hacky:
sometype.py:
def discover_some_type(data):
...some stuff i don't want done in a unit test...
discovery_channel.py:
import sometype
@datashape.discover.register(SomeType)
def discover_some_type(data):
return sometype.discover_some_type(data)
test_sometype.py:
class TestDiscoverSomeType(unittest.TestCase):
@patch('sometype.discover_some_type')
def test_discover_some_type(self, mock_discover_some_type):
import discovery_channel
file_to_discover = SomeType()
datashape.discover(file_to_discover)
mock_discover_some_type.assert_called_with(file_to_discover)
关键是你必须在导入具有将修补函数注册到datashape的修饰函数的模块之前修补实际做什么。不幸的是,这意味着你不能让你的装饰功能和在同一个模块中进行发现的功能(所以逻辑上应该在一起的东西现在是分开的)。你在单元测试中有一些hacky import-in-a-function(触发discover.register
)。但至少可行。