【问题标题】:Unit testing with Rspec and C extensions使用 Rspec 和 C 扩展进行单元测试
【发布时间】:2015-05-14 09:51:42
【问题描述】:

这些天似乎每个人都在谈论 TDD 和 BDD,所以我想在一个小型家庭项目上尝试一下。

一个简短的背景 我正在 C 扩展中开发一个类 Device,它与用于控制电灯开关等远程设备的原生 C API 交互。

为了使测试更加独立于平台,我模拟了 C API 以使其与原始 API 一样,但它设置了一个全局 ruby​​ 状态变量(包含所有 设备 的哈希),而不是控制硬件.

这一切都很好,并且可以按预期工作。我可以编译并链接到这个库而不是真正的库。

现在我需要帮助的部分是如何按照某种最佳实践对此进行测试我有以下规范来描述我的 Device

  describe Device do
    describe ".get" do
      context "Specified id exists" do
        it "Returns a instance of Device"
        it "Device has same id as specified"
      end
      context "Specified id is undefined"
        it "throws UndefinedDeviceException"
      end
    end
    describe "#turn_on" do
      context "Device supports turning on" do
        # I set up the mock state to have a device that supports on..
        # how do i get the Device instance here? is it ok to depend on
        # Device.get method?
        it "Returns true"
        it "Set device state to on" # Check mocked state
      end
    end
    .....
  end

现在,据我了解,在每种情况下,我都会为我的模拟库设置状态以反映我想要测试的内容并调用该方法。 这适用于静态方法Device.get(id),因为它返回一个新的Device,我不确定如何测试实例方法。如果我想测试 turn_on 方法,我首先需要有一个 Device 的实例,这意味着我需要调用 Device.get 来实际获取设备?但如果是这样的话,我又要“测试”类方法了吗?我想我在这里真正要问的是,如果它依赖于外部库,那么在 Rspec 中获取对象实例的好做法是什么。

【问题讨论】:

    标签: ruby unit-testing rspec tdd ruby-c-extension


    【解决方案1】:

    在我看来,调用Device.get 听起来很合适——在这些测试中,您将测试返回的 Device 对象的某些方法,而不是获取自身。

    虽然测试应该是独立的,但您最终会不可避免地遇到一些使用其他测试测试的方法的测试 - 例如,活动记录测试套件有大量针对 createfind 的测试,但这些方法是也被许多其他测试使用。

    这方面的棘手问题是决定要模拟的级别 - 您最终可能只测试您的模拟,而没有(或很少)实际实现。

    【讨论】:

    • 好吧,我猜我是在正确的轨道上。谢谢关于只是测试模拟,我想这是一个权衡。在我的特殊情况下,C API 的抽象级别相当大,所以我认为它值得测试。
    猜你喜欢
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 2011-02-07
    • 1970-01-01
    相关资源
    最近更新 更多