【问题标题】:How do you test a class with an extended module in ruby with spec您如何使用规范在 ruby​​ 中测试具有扩展模块的类
【发布时间】:2013-05-16 03:55:38
【问题描述】:

我永远无法为这个用例找到一个明确的答案,如果这是重复的,我深表歉意。在下面的示例中,是否有一种干净的方法可以使用 rspec 测试 B 类中的方法是否被调用?

module A
  def demo_method
    puts 1
  end
end

class B
  extend A
  demo_method
end

【问题讨论】:

  • 想想你是否关心类 B 中的方法被调用(特异性),或者你是否关心行为或结果。只要输出 1 并且方法返回 nil,那么它是 B 类的一部分还是从模块 A 派生并不重要,不是吗?
  • 我的真实例子是,在 Rails 模型中,我想确保调用这些方法。重要的是他们确实会被调用,并且有某种对他们的测试支持。您对此有什么建议吗?
  • 也许你应该简单地测试类的预期行为。大概你的方法 什么,所以你应该测试那个东西。测试“方法被调用”过于深入实施细节,IMO。
  • @davogones 与 rspec 匹配器有什么不同“它 { 应该 validate_presence_of(:name) }”
  • 验证某个属性是否存在是您的类的一种行为,这在规范中很重要。您所描述的内容(在定义类时应该调用某个方法)听起来更像是类的内部工作,对于消费者来说并不重要。所以我建议你测试方法的预期结果(公共行为),而不是测试方法是否被调用(私有实现细节)。

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2 rubygems


【解决方案1】:

首先将您的方法名称 method 修改为 demo_method,因为该名称很敏感。

然后

B.should respond_to :demo_method
# => true

【讨论】:

  • 这个问题是,它实际上并没有测试被调用的方法,这只是测试模块中定义的方法。
  • @ericraio,也许你可以使用B.should 'see something like puts 1',一旦定义或调用类,被调用的方法(“类宏”)将立即执行。
【解决方案2】:

如果你真的需要知道 B 类正在调用一个方法,你可以使用caller 方法。它会显示堆栈。

你会得到这种类型的堆栈输出:

$: ruby
how-do-you-test-a-class-with-an-extended-module-in-ruby-with-spec.rb 
how-do-you-test-a-class-with-an-extended-module-in-ruby-with-spec.rb:10:in
`<class:B>'
how-do-you-test-a-class-with-an-extended-module-in-ruby-with-spec.rb:8:in `<main>' 1
how-do-you-test-a-class-with-an-extended-module-in-ruby-with-spec.rb:14:in
`<main>' 1

你只需要输出caller

module A
  def demo_method
    puts caller
    puts 1
  end
end

class B
  extend A
  demo_method
end

puts B::demo_method

这些信息最好在调试级别的日志中提供,而不是在屏幕上。但我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2016-05-14
    • 1970-01-01
    • 2017-05-20
    • 2021-01-16
    • 2011-09-05
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多