Rails:如何测试lib/目录中的代码?

55

我有一个模型,它从解析器对象中获取数据。 我认为解析器类应该存储在lib /目录中(虽然我可能会被说服它应该存储在其他地方)。问题是:解析器类的单元测试应该放在哪里? 如何确保每次运行rake test时都会运行它们?

7个回答

30

我在开发的Rails应用中,决定把测试放在test\unit目录中。我还会按模块/目录进行嵌套,例如:

lib/a.rb   => test/unit/a_test.rb
lib/b/c.rb => test/unit/b/c_test.rb
对我而言,这是最后的抵抗之路,因为这些测试运行时无需进行其他任何更改。

5
@Qqwy,由于这在Rails 5上无法正常工作,那么在Rails 5.2上测试lib的最佳实践是什么? - Steven Aguilar
很遗憾,我不知道。 :-( - Qqwy

23

这是一种方法:

创建lib/tasks/test_lib_dir.rake文件,并添加以下内容:

namespace :test do

  desc "Test lib source"
  Rake::TestTask.new(:lib) do |t|    
    t.libs << "test"
    t.pattern = 'test/lib/**/*_test.rb'
    t.verbose = true    
  end

end

将您的lib目录结构复制到test目录下,并用相应的测试代码替换库代码。

运行rake test:lib来运行您的库测试。

如果您希望在调用rake test时运行所有测试,可以将以下内容添加到您的新rake文件中。

lib_task = Rake::Task["test:lib"]
test_task = Rake::Task[:test]
test_task.enhance { lib_task.invoke }

不知何故它无法加载环境(特别是 ActiveSupportfixtures),而且在 rakefile 中也没有强制它的方法。 - phil pirozhkov
1
嗨,我尝试了你的解决方案,rake test:lib 运行了我的测试,但是 rake test 没有运行。我完全复制了它。这里是我的文件内容链接:http://pastebin.com/FHMXU6vG。提前感谢! - robert

8

我也想用rspec和autospec完成同样的事情,但需要花费一些时间来找到它们获取测试文件列表所依据的目录/文件模式列表。最终,我在lib/tasks/rspec.rake:86中找到了这些信息。

  [:models, :controllers, :views, :helpers, :lib, :integration].each do |sub|
    desc "Run the code examples in spec/#{sub}"
    Spec::Rake::SpecTask.new(sub => spec_prereq) do |t|
      t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
      t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
    end
  end

当rpsec.rake文件配置为查找spec/lib目录时,我已经将我的测试放置在一个新的spec/libs目录中。只需将libs重命名为lib即可解决问题!


我在我的项目中默认有/lib文件夹。不幸的是,rake test无法捕获这些文件,因此只能使用RSpec,并且必须使用上述解决方案。 - phil pirozhkov

3
截至Rails 4.0
rake test:all         # Run all tests in any subdir of `test` without resetting the DB
rake test:all:db      # Same as above and resets the DB

截至 Rails 4.1,重新定义 test:run,在运行rakerake test时包括其他任务:
# lib/tasks/test.rake

namespace :test do
  Rake::Task["run"].clear
  task run: ["test:units", "test:functionals", "test:generators", "test:integration", "test:tasks"]

  ["tasks"].each do |name|
    Rails::TestTask.new(name => "test:prepare") do |t|
      t.pattern = "test/#{name}/**/*_test.rb"
    end
  end
end

这样做的附加好处是在给定示例中定义了rake test:tasks
Rails 4.2开始,test:run包含test的所有子目录,当运行rake testrake时也包括它们。

5
在Rails 5中,这些不同的任务已经不存在了。 - Qqwy

3

一种简单而干净的方法是在test/unit/lib目录下创建一个文件夹。然后,创建测试文件test/unit/lib/foo_test.rb对应于lib/foo.rb。无需创建新的rake任务,并且如果需要匹配lib目录结构,则可以嵌套更多目录。


0
为了不定义额外的rake任务来运行自定义文件夹中的测试,您也可以使用命令rake test:all来运行它们。对于lib文件夹或任何其他自定义文件夹的测试文件夹结构由您决定。但我更喜欢将它们复制到类中:lib匹配到test/libapp/form_objects匹配到test/form_objects

-3

使用:

[spring] rake test:all

运行所有测试,包括您创建的目录(例如[root]/test/lib/)。

如果您没有使用它,请省略[spring]


rake 中止!不知道如何构建任务 'test:all'。 - user160917

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接