【问题标题】:How do I properly use mock functionality for testing purposes in Rails?如何在 Rails 中正确使用模拟功能进行测试?
【发布时间】:2011-10-08 21:51:15
【问题描述】:

我是使用 mixins 的新手,我更熟悉基于 Java 的依赖注入。

假设我使用 mixin 模块为类提供数据库连接,如 http://fabiokung.com/2010/05/06/ruby-and-dependency-injection-in-a-dynamic-world/ 所述:

module ConnectionProvider
  def connection
    # open a database connection and return it
  end
end

# reopening the class to mix the module in
class Repository
  include ConnectionProvider
end

这让我可以这样做:

class Repository
  def find(id)
    connection.execute("SELECT ...")
  end
end

现在我不必通过 Repository 初始化程序传入 ConnectionProvider 对象。

假设我想使用模拟版本的 ConnectionProvider 进行测试,因此我想在 Repository 中包含 MockConnectionProvider 而不是 ConnectionProvider。 ConnectionProvider 和 MockConnectionProvider 都提供方法connection。这是我认为应该这样做的方式。


对于我的普通 Rails 应用程序

在 environment.rb 中:

require File.dirname(__FILE__) + "/../lib/repository"

对于我的测试脚本

在我的测试文件中:

require File.dirname(__FILE__) + "/../lib/repository_mocked"

这是正确的吗?如果没有,有人可以提供一篇文章的链接来演示正确的方法吗?

【问题讨论】:

    标签: ruby-on-rails mocking mixins


    【解决方案1】:

    您应该使用模拟库来执行此类操作。我通常使用mocha,它有一个很好的界面,你可以编写类似的代码

    mocked_value = # anything you want
    Repository.any_instance.stubs(:find).returns(mocked_value)
    

    所以每次调用Repository#find 都会返回mocked_value

    其他模拟库有:

    【讨论】:

      【解决方案2】:

      您可以只模拟“连接”方法。

      由于模块已包含在类中,其方法被视为此类的方法。

      如果你想模拟一堆相关的方法,你可以重写你的类,它使用 ConnectionProvider 类的实例(是的,将它从​​模块更改为类)。所以这样就可以mock这个ConnectionProvider实例对象了。

      UPD:你不应该为了模拟而弄乱文件。使用 Fabio 告诉您的特殊模拟工具。 ;)

      【讨论】:

        猜你喜欢
        • 2018-05-14
        • 1970-01-01
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        • 2022-11-16
        • 2020-01-05
        • 2020-06-12
        • 1970-01-01
        相关资源
        最近更新 更多