简体   繁体   English

Rails - 测试夹具错误NoMethodError:nil的未定义方法`type':NilClass

[英]Rails - Testing fixtures error NoMethodError: undefined method `type' for nil:NilClass

I have a problem running tests that use fixtures with associations between models. 我在运行使用具有模型之间关联的夹具的测试时遇到问题。

Here's the error I get, as soon as I run rake test : 一旦我运行rake test ,这就是我得到的错误:

ERROR["test_truth", SevenPortfolioTest, 0.005154775]
 test_truth#SevenPortfolioTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_destroy_item_video", SevenPortfolio::ItemVideosControllerTest, 0.008887804]
 test_should_destroy_item_video#SevenPortfolio::ItemVideosControllerTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_index", SevenPortfolio::ItemVideosControllerTest, 0.011364416]
 test_should_get_index#SevenPortfolio::ItemVideosControllerTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_create_item_video", SevenPortfolio::ItemVideosControllerTest, 0.014584266]
 test_should_create_item_video#SevenPortfolio::ItemVideosControllerTest (0.01s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_new", SevenPortfolio::ItemVideosControllerTest, 0.017282812]
 test_should_get_new#SevenPortfolio::ItemVideosControllerTest (0.02s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_update_item_video", SevenPortfolio::ItemVideosControllerTest, 0.019729858]
 test_should_update_item_video#SevenPortfolio::ItemVideosControllerTest (0.02s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_edit", SevenPortfolio::ItemVideosControllerTest, 0.022365633]
 test_should_get_edit#SevenPortfolio::ItemVideosControllerTest (0.02s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_destroy_item", SevenPortfolio::ItemsControllerTest, 0.025860205]
 test_should_destroy_item#SevenPortfolio::ItemsControllerTest (0.03s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_edit", SevenPortfolio::ItemsControllerTest, 0.030867796]
 test_should_get_edit#SevenPortfolio::ItemsControllerTest (0.03s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_show_item", SevenPortfolio::ItemsControllerTest, 0.036687105]
 test_should_show_item#SevenPortfolio::ItemsControllerTest (0.04s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_update_item", SevenPortfolio::ItemsControllerTest, 0.040130774]
 test_should_update_item#SevenPortfolio::ItemsControllerTest (0.04s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_create_item_with_video", SevenPortfolio::ItemsControllerTest, 0.042776553]
 test_should_create_item_with_video#SevenPortfolio::ItemsControllerTest (0.04s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_index", SevenPortfolio::ItemsControllerTest, 0.045301694]
 test_should_get_index#SevenPortfolio::ItemsControllerTest (0.05s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_get_new", SevenPortfolio::ItemsControllerTest, 0.048094189]
 test_should_get_new#SevenPortfolio::ItemsControllerTest (0.05s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass


ERROR["test_should_create_item_with_gallery", SevenPortfolio::ItemsControllerTest, 0.051019403]
 test_should_create_item_with_gallery#SevenPortfolio::ItemsControllerTest (0.05s)
NoMethodError:         NoMethodError: undefined method `type' for nil:NilClass

I'm testing a rails engine. 我正在测试一个rails引擎。 Here's my fixtures: 这是我的装置:

# test/fixtures/seven_portfolio/items.yml
item_one:
  description: item one description
  finished_at: <%= 7.days.ago %>
  is_featured: true
  item_type: 0

item_two:
  description: item two description
  finished_at: <%= 6.days.ago %>
  is_featured: false
  item_type: 1


# test/fixtures/seven_gallery/galleries.yml
gallery_one:
  title: seven_gallery_gallery_one_title
  item: item_one

# test/fixtures/seven_gallery/photos.yml
photo_one:
  caption: photo_one_caption
  gallery: gallery_one

# test/fixtures/seven_portfolio/item_videos.yml
one:
  item: item_one

When, for example, I remove item: item_one and similar associations lines. 例如,当我删除item: item_one和类似的关联item: item_one The test works well. 测试效果很好。

-- EDIT - 编辑

Here's the backtrace 这是回溯

Command failed with status (1): [ruby -I"lib:lib:test"  "/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/rake_test_loader.rb" "test/**/*_test.rb" ]

/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/testtask.rb:108:in `block (3 levels) in define'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils.rb:57:in `call'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils.rb:57:in `sh'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils_ext.rb:37:in `sh'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils.rb:96:in `ruby'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils_ext.rb:37:in `ruby'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/testtask.rb:104:in `block (2 levels) in define'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/file_utils_ext.rb:58:in `verbose'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/testtask.rb:100:in `block in define'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:240:in `call'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:235:in `each'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:235:in `execute'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/task.rb:165:in `invoke'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:150:in `invoke_task'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:106:in `block (2 levels) in top_level'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:106:in `each'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:106:in `block in top_level'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:115:in `run_with_threads'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:100:in `top_level'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:78:in `block in run'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling'
/home/rafael/.rbenv/versions/2.2.0/lib/ruby/2.2.0/rake/application.rb:75:in `run'
/home/rafael/.rbenv/versions/2.2.0/bin/rake:33:in `<main>'

EDIT 编辑

Here's Item class: 这是Item类:

module SevenPortfolio
  class Item < ActiveRecord::Base
    has_one :item_video, class_name:'SevenPortfolio::ItemVideo', foreign_key: "seven_portfolio_item_id"
    has_one :item_gallery, class_name: 'SevenGallery::Gallery', foreign_key: "seven_portfolio_item_id"
    accepts_nested_attributes_for :item_video, :item_gallery

    before_save :process_type

    def process_type
      self.build_item_video if self.item_type == 0
      self.build_item_gallery if self.item_type == 1
    end

    def type_content
      self.item_gallery if self.item_type == 0
      self.item_video if self.item_type == 1
    end
  end
end

And Gallery class: Gallery类:

class SevenGallery::Gallery < ActiveRecord::Base
  include SevenGallery::Concerns::Gallery
  belongs_to :item, :class_name => 'SevenPortfolio::Item'
end

EDIT Here's the schema.rb file: 编辑这是schema.rb文件:

ActiveRecord::Schema.define(version: 20150414145951) do

  create_table "seven_gallery_galleries", force: :cascade do |t|
    t.string   "title",                   limit: 255
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.integer  "seven_portfolio_item_id", limit: 4
  end

  add_index "seven_gallery_galleries", ["seven_portfolio_item_id"], name: "index_seven_gallery_galleries_on_seven_portfolio_item_id", using: :btree

  create_table "seven_gallery_photos", force: :cascade do |t|
    t.string   "caption",                  limit: 255
    t.string   "image",                    limit: 255
    t.integer  "seven_gallery_gallery_id", limit: 4
    t.datetime "created_at",                                             null: false
    t.datetime "updated_at",                                             null: false
    t.boolean  "is_new",                   limit: 1,     default: true
    t.boolean  "is_featured",              limit: 1,     default: false
    t.text     "description",              limit: 65535
    t.string   "alt",                      limit: 255
    t.integer  "position",                 limit: 4,     default: 0
  end

  add_index "seven_gallery_photos", ["seven_gallery_gallery_id"], name: "index_seven_gallery_photos_on_seven_gallery_gallery_id", using: :btree

  create_table "seven_portfolio_item_videos", force: :cascade do |t|
    t.string   "url",                     limit: 255
    t.text     "description",             limit: 65535
    t.string   "title",                   limit: 255
    t.integer  "seven_portfolio_item_id", limit: 4
    t.datetime "created_at",                            null: false
    t.datetime "updated_at",                            null: false
  end

  add_index "seven_portfolio_item_videos", ["seven_portfolio_item_id"], name: "index_seven_portfolio_item_videos_on_seven_portfolio_item_id", using: :btree

  create_table "seven_portfolio_items", force: :cascade do |t|
    t.datetime "created_at",                                null: false
    t.datetime "updated_at",                                null: false
    t.text     "description", limit: 65535
    t.date     "finished_at"
    t.boolean  "is_featured", limit: 1,     default: false
    t.integer  "item_type",   limit: 4,     default: 0
  end

  add_foreign_key "seven_gallery_galleries", "seven_portfolio_items", on_delete: :cascade
  add_foreign_key "seven_gallery_photos", "seven_gallery_galleries", on_delete: :cascade
  add_foreign_key "seven_portfolio_item_videos", "seven_portfolio_items", on_delete: :cascade
end

I've hit the same errors after migrating and rolling back a few times in my dev environment. 在我的开发环境中迁移和回滚几次后,我遇到了同样的错误。 It's something to do with the "_type" column. 这与“_type”列有关。

The only thing that fixed it for me was a drop/create of the test database: 为我修复它的唯一方法是删除/创建测试数据库:

bundle exec rake db:reset RAILS_ENV=test

Be confident your schema.rb is in good shape before doing this. 在执行此操作之前,请确保您的schema.rb处于良好状态。

This error happen when in you model you create a relationship that doesnt have a field in the db. 在模型中创建一个在db中没有字段的关系时会发生此错误。 Example: 例:

class Contact < ActiveRecord::Base
 belongs_to account
end

But in your table contacts: 但在你的表联系人:

create_table "contacts", force: :cascade do |t|
    t.string   "fname"
    t.string   "lname"
    t.string   "title"
    t.string   "description"
    t.datetime "created_at",                 null: false
    t.datetime "updated_at",                 null: false
    t.boolean  "primary"
    t.integer  "contactable_id"
    t.integer  "contactable_type"
  end

See there's no account_id field. 看到没有account_id字段。

In my case I forgot to update the model's belongs_to to be polymorphic: 在我的情况下,我忘了更新模型的belongs_to是多态的:

class Contact < ActiveRecord::Base
  belongs_to :contactable, polymorphic: true
end

class Account < ActiveRecord::Base
  has_many :contacts, as: :contactable
end

Is this not a duplicate/similar problem to this issue? 这不是这个问题的重复/类似问题吗?

Loading Rails Fixtures in a Specific Order when Testing 测试时按特定顺序装载导轨夹具

What could be happening is your fixtures are not being loaded in the correct order so when item is referenced it comes up as nil. 可能发生的事情是你的灯具没有以正确的顺序加载,因此当引用项目时它会出现为零。

From the response of the other answer you can try 从其他答案的回答你可以尝试

Here's how you fix your issue: 以下是解决问题的方法:

  1. Log into Postgresql with your default superuser (mine is "postgres") Perform the following command: 使用默认超级用户登录Postgresql(我的是“postgres”)执行以下命令:

  2. ALTER ROLE yourtestdbuser WITH SUPERUSER; ALTER ROLE yourtestdbuser with SUPERUSER;

  3. Enjoy your properly working fixtures. 享受你正常工作的灯具。

If you are using mysql it is probably similar issue. 如果您使用的是mysql,那可能是类似的问题。

TL;DR: People are landing on this question for different reasons. TL; DR:人们出于不同的原因登陆这个问题。 My problem/solution is described in 'Fixing the error'. 我的问题/解决方案在“修复错误”中描述。 I hope this extended explanation will help you learn why you're experiencing this cryptic error, and save you some time debugging it. 我希望这个扩展的解释将帮助您了解为什么您遇到这个神秘的错误,并节省您一些时间调试它。

How to diagnose this issue 如何诊断这个问题

I had almost the same error when running my tests: NoMethodError: undefined method 'id' for nil:NilClass , or NoMethodError: undefined method 'each' for nil:NilClass . 我在运行测试时遇到了几乎相同的错误: NoMethodError: undefined method 'id' for nil:NilClass ,或NoMethodError: undefined method 'each' for nil:NilClass There were no line numbers to reference, and Lucas' answer of rebuilding would sometimes work and then would stop working; 没有行号可供参考, 卢卡斯的重建答案 有时会起作用,然后就会停止工作; I'd later learn this is because of caching and loading order of fixture files. 我后来才知道这是因为夹具文件的缓存和加载顺序。

Finding where the error is thrown 查找抛出错误的位置

My error was with how my fixtures were setup. 我的错误在于如何设置我的灯具。 I found this by running my tests with a full backtrace described in this StackOverflow answer : 我通过在StackOverflow回答中描述的完整回溯运行我的测试找到了这个:

BACKTRACE=YES rake test test/controllers/document_submissions_controller_test.rb

This pointed to the gem files in ActiveSupport that were throwing the error. 这指向ActiveSupport中抛出错误的gem文件。 Here's my full log for a single test: 这是我单个测试的完整日志:

在此输入图像描述

So it seems the error is in loading my fixtures, since the error is originating in active_record/fixtures.rb:758 (see highlighted line above). 所以似乎错误在于加载我的灯具,因为错误源自active_record/fixtures.rb:758 (见上面突出显示的行)。 However, I have a large amount of fixtures in my app, I needed to narrow down which in particular was causing the problem. 但是,我的应用程序中有大量的灯具,我需要缩小范围,特别是导致问题。

Setting a break point 设置一个断点

I opened the active_record/fixtures.rb:758 file in my code editor using the command below: 我使用以下命令在代码编辑器中打开了active_record/fixtures.rb:758文件:

code /Users/mattmcinnis/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.0/lib/active_record/fixtures.rb

Note: I'm using VSCode with the code command, but any code editor will do. 注意:我正在使用VSCode和code命令,但任何代码编辑器都可以。

On line 758 where the error occurs, I saw this code: 在发生错误的第758行,我看到了这段代码:

FixtureSet::File.open(file) do |fh|
  fh.each do |fixture_name, row|  # line 758
    fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
  end 
end

..which I wrapped in a rescue block, and modified to: ..我在救援区包裹,并修改为:

FixtureSet::File.open(file) do |fh|
  begin
    fh.each do |fixture_name, row|
      fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
    end
  rescue
    debugger
  end
end

NOTE: Be sure to revert any changes to this file when you're done! 注意:完成后,请务必还原对此文件的任何更改!

Finding the problem file 查找问题文件

I'm interested in which file, captured in the loop above in the variable fh , was causing the error. 我感兴趣的是在变量fh上面循环中捕获的文件导致了错误。 Running my test suite again I hit my breakpoint and found the filename that was causing the problem: 再次运行我的测试套件我点击我的断点并找到导致问题的文件名:

> (byebug) fh
  => ... @file="permissions.yml"

Fixing the error 修复错误

In my permissions.yml file, my fixture is referring to a related model by hard coding the 'id' in, instead of referring by name: 在我的permissions.yml文件中,我的fixture通过硬编码'id'来引用相关模型,而不是通过名称引用:

Ex. 防爆。 permissions.yml

permission1:
  ...
  user_id: <%= User.first.id %>  # Bad!

Fixing the last line to something like, user: user1 to refer to the user1 fixture in users.yml solved the issue. 修复最后一行,例如user: user1引用users.ymluser1 fixture解决了这个问题。

Hope this helps someone. 希望这有助于某人。 I lost half a day on this one, and found it super hard to diagnose. 我在这一天失去了半天,发现诊断起来非常困难。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NoMethodError:nil的未定义方法&#39;type&#39;:Rails中的NilClass - NoMethodError: Undefined method 'type' for nil:NilClass in Rails &quot;NoMethodError: undefined method `env&#39; for nil:NilClass&quot; 用于 Rails 中的 Helper 测试 - "NoMethodError: undefined method `env' for nil:NilClass" for Helper testing in rails &#39;NoMethodError:使用rails进行功能测试时,nil:NilClass&#39;的未定义方法`scan&#39; - 'NoMethodError: undefined method `scan' for nil:NilClass' when functional testing with rails Rails:“ NoMethodError(对于nil:NilClass的未定义方法&#39;underscore&#39;)上的错误:” - Rails: Error on 'NoMethodError (undefined method `underscore' for nil:NilClass):' Rails控制台错误:nil的未定义方法`each&#39;:NilClass(NoMethodError) - Rails console error: undefined method `each' for nil:NilClass (NoMethodError) Rails:错误“ NoMethodError:nil:NilClass的未定义方法&#39;&lt;&#39;”,缺少一些gem吗? - Rails: Error “NoMethodError: undefined method `<' for nil:NilClass”, missing some gem? Rails4:NoMethodError /未定义的方法&#39;*&#39;为nil:NilClass - Rails4: NoMethodError / undefined method `*' for nil:NilClass Rails-NoMethodError-未定义的方法“名称”,为nil:NilClass - Rails - NoMethodError - undefined method `name' for nil:NilClass Rails 6-NoMethodError(nil:NilClass的未定义方法“ titleize”) - Rails 6 - NoMethodError (undefined method `titleize' for nil:NilClass) Rails 4:NoMethodError:nil的未定义方法`each&#39;:NilClass - Rails 4: NoMethodError: undefined method `each' for nil:NilClass
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM