如何在Rails中正确使用模拟功能进行测试?

时间:2011-07-19 21:08:15

标签: ruby-on-rails mocking mixins

我是使用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"

这是对的吗?如果没有,有人可以提供链接到展示正确方法的文章吗?

2 个答案:

答案 0 :(得分:1)

您应该使用模拟库来执行此类操作。我通常使用具有良好界面的mocha,你可以编写像

这样的代码
mocked_value = # anything you want
Repository.any_instance.stubs(:find).returns(mocked_value)

因此,对Repository#find的每次通话都会返回mocked_value

其他模拟库是:

答案 1 :(得分:0)

你可以模拟'连接'方法。

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

如果你想模拟一堆相关的方法,你可以重写你的类,它使用一个ConnectionProvider类的实例(是的,从模块中将它改为类)。因此,您可以通过这种方式模拟此ConnectionProvider实例对象。

UPD:你不应该乱用文件进行嘲弄。 Fabio告诉你,使用特殊的模拟工具。 ;)