python - 谁在 "don' t 模拟第 3 方”和 "ensure close() called"之间的战斗中获胜?

标签 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 集成的测试,而不是模拟它(不要模拟第 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/

相关文章:

clojure - 在 Clojure 中模拟现有方法

python - 使用 python 和 GObject 在 glade 中添加组合框

python - 命令 PhaseScriptExecution 失败,退出代码非零,Xcode 10.1 dyld : Library not loaded:/usr/local/opt/readline/lib/libreadline. 7.dylib

Python - 将枚举转换为 Django models.CharField 选择元组

unit-testing - 单元测试(模拟)数据库,如何使用模拟验证数据库方法?

unit-testing - 如何为Grails中的功能测试设置测试数据?

python - 为什么使用**kwargs时会出现 'kwargs'这个键?

azure - 如何在流分析作业查询中模拟 System.Timestamp()?

java - junit:使用mockmvc测试 Controller 时注入(inject)bean上的NullPointer

ruby-on-rails - RSpec - 模拟类方法