我有这段代码要进行单元测试:
@staticmethod
def _read_from_zip(pkg_zip_path):
"""
Return a |BlobCollection| instance loaded from *pkg_zip_path*.
"""
blobs = BlobCollection()
zipf = ZipFile(pkg_zip_path)
for name in zipf.namelist():
blobs[name] = zipf.read(name)
zipf.close()
root_uri = os.path.splitext(pkg_zip_path)[0]
return PhysPkg(blobs, root_uri)
它调用 ZipFile,一个库/第三方包,所以我想编写一个与 ZipFile 集成的测试,而不是模拟它(不要模拟第 3 方代码规则)。
这是我目前的测试。 initializer_mock()
是一个辅助函数,用于修补类上的 __init__()
方法,在这种情况下为 PhysPkg
:
from opcdiag.phys_pkg import PhysPkg
MINI_PKG_PATH = 'test_files/mini_pkg.zip'
@pytest.fixture
def init(self, request):
return initializer_mock(PhysPkg, request)
def it_can_construct_from_a_zip_package(self, init):
PhysPkg._read_from_zip(MINI_PKG_PATH)
expected_blobs = {'uri_1': b'blob_1\n', 'uri_2': b'blob_2\n'}
init.assert_called_once_with(expected_blobs, ROOT_URI)
问题是,因为我没有模拟 ZipFile,所以我不知道如何测试调用了 close()
方法。
也许我应该写两个测试?一个是通过测试结果确保与 ZipFile 的正确集成,另一个是通过模拟 ZipFile 确保 close()
被调用?
最佳答案
是的,您应该编写 2 个测试。或者您可以为您的库创建一个代理,它转发每个方法,但计算 close
被调用的次数。
我使用 proxy
而不是 mock
是有原因的。您没有替换它(就像模拟对象通常做的那样)。您只是添加了一个透明层。
您“不模拟第 3 方库”的原因是您需要测试它们(尤其是当您更新它们或可能想要更新它们时)。一种选择是信任提供者。另一个是创建一个完整的测试。第三个(是的,由“不要模拟第 3 方库”提倡的那个)是仅在您的软件有效使用它们的那些方面测试它们。 proxy mock
不会改变这一点。
关于python - 谁在 "don' t 模拟第 3 方”和 "ensure close() called"之间的战斗中获胜?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18555949/