【问题标题】:Mocking the filesystem in C在 C 中模拟文件系统
【发布时间】:2011-12-16 20:22:14
【问题描述】:

我开始用 C 语言编写一个简单的程序,并且想将配置存储在磁盘上。为了促进正确和正确的单元测试,我想做一些事情来防止被测代码实际读取和写入磁盘。

配置文件格式,为了参数是YAML。

程序的 API 可能类似于:

myapp config

会转储整个配置。 (有预先存在的配置文件/模拟)

myapp config server

将转储服务器子密钥。 (有预先存在的配置文件/模拟)

myapp config server=example.com

会用新值写入文件(无论是否有一个预先存在的文件)

在内部,配置只是一个结构,其中包含少量密钥、服务器主机、服务器端口和用于进行一些 API 调用的用户名。

我一点也不担心文件在磁盘(目录)上的位置或 getopt/CLI 解析,只是如何模拟网络和文件系统操作对我来说很重要。

问题更进一步,即询问可以使用哪些技术来存根网络

我很可能会使用 cmockery 和 libcurl。

我的第一个想法是“也许我应该做一个像 read_configuration_file() 这样的函数,我可以在我的单元测试中模拟”,但我真的不确定这样做的优点,ruby 中的代码存根文件系统可能很简单:

File.stubs(:read).with('./configuration.yml').returns("---\nserver: example.com\n")

而且,在这种背景下,以C 的术语思考,我发现这很困难。

我观察到似乎没有多少人用 C 语言测试这些东西,或者更具体地说,如果他们这样做了 - 他们并没有写关于它的文章。

注意:这不是作业问题,只是在我写完整个东西后听起来有点像,我实际上只是在尝试学习 C,来自 Ruby背景;您可能会注意到我关于尝试做 C "right" 的其他一些问题。

【问题讨论】:

    标签: c mocking cmake


    【解决方案1】:

    您可能想看看 CUNIT 的开发人员做了什么,看看您是否可以避免重新发明部分轮子

    http://sourceforge.net/projects/cunit/

    【讨论】:

    • 看起来最好的选择是“不要存根读取的文件”,而是“确保您的测试读取您控制的文件”——这就是他们对 static FILE* temp_file = NULL; 所做的事情 - 我我猜只需要存根确定要读取哪个文件的函数,然后让 stdlib 来做这件事!感谢链接 CUnit 似乎比 CMockery 更平易近人
    【解决方案2】:

    我认为你的前提

    “为了促进正确和正确的单元测试,我想做 阻止被测代码实际读取的东西,以及 写入磁盘。”

    错了。您始终可以安排从新创建的空目录或您可能想要的任何预先安排的状态运行测试。这对测试的正确性有何影响?

    【讨论】:

    • 如果它有任何外部依赖关系,它不是单元测试不是真的吗? – 您是否碰巧知道如何使用多个可能的输入来测试成功以及文件解析的失败条件,那么每个单独的单元测试是否必须在具有正确数据夹具的沙箱中运行?
    • 对使用文件系统的 ruby​​ 程序的单元测试与使用它的 C 程序具有所有相同的依赖关系。红宝石除外。
    • 除了 Ruby 中的单元测试有一个模拟库,这意味着我可以轻松地将被测输入提供给我的实现。
    • 如果您的程序旨在操作文件,那么实际上如何使用文件系统作为“外部依赖项”?无论如何,您必须设置夹具;将测试文件写入物理文件并从那里读取或人为地输入程序有什么区别?我认为你过于复杂了。
    • 只有在 chroot 中运行 my test suite 才将我限制在一个模拟文件中,这是一个问题。尽管正如上面与@TomDignan 所讨论的那样,在我的代码中覆盖which_configuration_file() 方法以将模拟文件提供给程序可能是可行的。它还可能要求我使用 chroot,或者至少更改 pwd
    猜你喜欢
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    相关资源
    最近更新 更多