2

我有这段代码要进行单元测试:

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

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

4

1 回答 1

1

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

我使用这个词proxy而不是mock出于某种原因。您不会替换它(就像模拟对象通常那样)。您只是添加了一个透明层。

您“不模拟 3rd 方库”的原因是您需要测试它们(尤其是当您更新它们或可能想要更新它们时)。一种选择是信任提供者。另一个是创建一个完整的测试。第三个(是的,由“不要模拟第三方库”所提倡的那个)是仅在您的软件有效使用它们的那些方面测试它们。Aproxy mock不会改变这一点。

于 2013-09-01T06:55:35.960 回答