在模型上运行测试时如何禁止数据库创建?

时间:2017-09-11 21:19:10

标签: ruby-on-rails database testing model ruby-on-rails-5

我试图为我的模型编写一个简单的测试,但我不需要创建数据库。我添加了以下文件以防止数据库创建

myenv:myproject nataliab$ cat lib/tasks/db/test.rake
Rake.application.remove_task 'db:test:prepare'

namespace :db do
  namespace :test do
    task :prepare do |t|
      # rewrite the task to not do anything you don't want
    end
  end
end

但是当我运行测试时,我仍然会收到以下错误

myenv:myproject nataliab$ rails test -b test/models/my_model_test.rb
Running via Spring preloader in process 52504
/Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `async_exec': PG::InsufficientPrivilege: ERROR:  permission denied for relation schema_migrations (ActiveRecord::StatementInvalid)
: SELECT "schema_migrations".* FROM "schema_migrations"
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `block in exec_no_cache'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:590:in `block in log'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/abstract_adapter.rb:583:in `log'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `exec_no_cache'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/postgresql_adapter.rb:585:in `execute_and_clear'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:103:in `exec_query'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:377:in `select_prepared'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:39:in `select_all'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/connection_adapters/abstract/query_cache.rb:95:in `select_all'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/querying.rb:39:in `find_by_sql'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/relation.rb:702:in `exec_queries'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/relation.rb:583:in `load'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/relation.rb:260:in `records'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/relation/delegation.rb:38:in `map'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:1031:in `block in get_all_versions'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/deprecation/reporting.rb:36:in `silence'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/deprecation/instance_delegator.rb:20:in `silence'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:1029:in `get_all_versions'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:1043:in `needs_migration?'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:577:in `load_schema_if_pending!'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:592:in `block in maintain_test_schema!'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:823:in `suppress_messages'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:597:in `method_missing'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.5/lib/active_record/migration.rb:592:in `maintain_test_schema!'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/test_help.rb:14:in `<top (required)>'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `block in require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/Documents/workspace/myproject/test/test_helper.rb:3:in `<top (required)>'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `block in require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/Documents/workspace/myproject/test/models/my_model_test.rb:1:in `<top (required)>'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `block in require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/test_unit/runner.rb:48:in `block in load_tests'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/test_unit/runner.rb:48:in `each'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/test_unit/runner.rb:48:in `load_tests'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/test_unit/runner.rb:39:in `run'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/commands/test.rb:10:in `<top (required)>'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `block in require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:259:in `load_dependency'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/commands/commands_tasks.rb:138:in `require_command!'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/commands/commands_tasks.rb:95:in `test'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.5/lib/rails/commands.rb:18:in `<top (required)>'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:293:in `block in require'
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/activesupport-5.0.5/lib/active_support/dependencies.rb:259:in `load_dependency'

我还需要做些什么来防止发生任何数据库活动?

2 个答案:

答案 0 :(得分:1)

ActiveRecord与DB紧密耦合,这是不可行的。在解决迁移表的需求之后,您将不得不解决这样一个事实:创建模型的属性需要DB(它会读取数据库列),之后我就不会这样做了。知道你面前的是什么,但我敢打赌,你甚至不会接近完成猴子修补AR(我可能错了)。

这就是rails完成的方式。

你可以做的就是拥有继承自AR(无桌面型号)的模型,这些模型正在做你想做的任何事情,并且只在其他经典的#34;中使用它们。楷模?

我,通常情况下,当遇到这样一个难题时,请将其作为一种暗示,即你试图用头脑穿过墙壁&#34; (墙是这里的框架,其设计不是为了解决这个问题)并尝试考虑不同的设计(如上所述:&#34;无表格&#34;模型)。

如果没有项目的更多细节,很难提出更具体的建议。

答案 1 :(得分:0)

如果你真的想在不使用DB的情况下测试方法,那么首先不要将它放在模型中。相反,你可以将它放在一个模块中(轨道用语中的一个问题):

# app/models/concerns/foo.rb
module Foo
  def bar
    'Hello world'
  end
end

然后,您只需在测试中创建一个由模块扩展的类:

require "minitest/autorun"
require "active_model/model"

class TestFoo < Minitest::Test
  def setup
    @klass = Class.new do
      include ActiveModel::Model 
      include Foo
    end
  end

  def test_bar
    assert_equal 'Hello world', @klass.new.bar
  end
end

包括ActiveModel::Model使得测试替换的行为与任何其他模型一样,但没有持久层。

否则,因为meagar和meta已经声明试图测试一个继承自ActiveRecord::Base而没有DB的类是徒劳的。在没有数据库的情况下对模型进行单元测试的整个想法存在严重缺陷,因为ActiveRecords模型真正做的是与数据库进行交互。

只需编写一个涵盖实际实施的单一测试,就可以获得更好的敏锐度,这在我的书中任何一天都能胜过一些原教旨主义的单元测试。