谁在“不要嘲笑第三方”和“确保关闭()被称为”之间的战斗中获胜?

时间:2013-09-01 06:42:45

标签: python unit-testing mocking

我有这个代码块,我想进行单元测试:

@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集成的测试而不是模拟它(不要模拟第三方代码规则)。

这是我到目前为止的测试。 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()被调用?

1 个答案:

答案 0 :(得分:1)

是的,你应该写2个测试。或者,您可以为库创建一个转发每个方法的代理,但计算close被调用的次数。

我使用proxy这个词而不是mock是有原因的。你没有替换它(通常是模拟对象)。你只是添加一个透明层。

你“不模仿第三方库”的原因是你需要测试它们(特别是当你更新它们或者想要更新它们时)。一种选择是信任提供者。另一个是创建一个完整的测试。而第三个(是的,由“不要模仿第三方库”推广的那个)是仅在软件有效使用它们的那些方面测试它们。 proxy mock不会改变这一点。