运行规范时出现的描述性错误,取决于种子

我编写了一个function规范来测试我的应用程序中的正确多租户行为。 它以两个不同的用户身份登录,通过填写表单并将其作为每个用户提交来创建新的Presentation ,并在每次只有租户自己的演示文稿可见时确认。

这个规范有时很好,有时也没有。 真正令人困惑的是发生的错误:

 Failure/Error: click_button "Präsentation erstellen" TypeError: can't cast ActiveSupport::HashWithIndifferentAccess to # ./app/controllers/presentations_controller.rb:21:in `create' # ./spec/features/presentation_management_spec.rb:22:in `block (3 levels) in ' 

并且这不是粘贴时的错误,它字面上说can't cast ActiveSupport::HashWithIndifferentAccess to并停在那里。 上下文中引用的行:

./app/controllers/presentations_controller.rb

 18 def create 19 @presentation = Presentation.new(presentation_params) 20 21 if @presentation.save 22 flash_for(@presentation, :create) 23 redirect_to @presentation 24 else 25 render :new 26 end 27 end 

./spec/features/presentation_management_spec.rb

 16 sign_in @user1 17 18 visit new_presentation_path 19 fill_in "Titel", with: title1 20 fill_in "Standard-Foliendauer", with: "60" 21 22 click_button "Präsentation erstellen" 23 24 page.should have_content "erfolgreich erstellt" 25 page.should have_content title1 

我没有看到这个错误在这里有什么意义,我只是点击一个按钮,它将创建一个新的演示文稿并保存它。 保存本身会引发错误。 怎么样? 为什么?

更糟糕的是, 这只发生在一些rspec种子上 。 例如, 48719运行良好:

 .......................................................................................... Finished in 48.17 seconds 90 examples, 0 failures Randomized with seed 48719 

这意味着只有规范的某些执行顺序才会发生此错误。 但该错误根本不具有描述性,我不知道该怎么做。 我已经尝试重置所有数据库,重新启动整个服务器,打印出按下按钮的页面,注释掉不同的行,没有任何改变,甚至暗示可能出错的地方。

这是我的演示模型:

  class Presentation < ActiveRecord::Base store_accessor :properties, :bg_color, :bg_image validates :title, presence: true validates :default_duration, presence: true, numericality: { greater_than_or_equal_to: 1 } def to_s title end end 

编辑 :我检查了测试日志,发现是一个失败的案例:

  SQL (1.3ms) INSERT INTO "presentations" ("created_at", "default_duration", "properties", "title", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Tue, 04 Feb 2014 20:56:26 UTC +00:00], ["default_duration", 60.0], ["properties", {"bg_ color"=>"#ffffff"}], ["title", "Example Presentation yo"], ["updated_at", Tue, 04 Feb 2014 20:56:26 UTC +00:00]] TypeError: can't cast ActiveSupport::HashWithIndifferentAccess to : INSERT INTO "presentations" ("created_at", "default_duration", "properties", "title", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" (1.6ms) ROLLBACK TO SAVEPOINT active_record_1 Completed 500 Internal Server Error in 10ms 

这里唯一的Hash是{"bg_color"=>"#ffffff"} ,分配给propertiesproperties字段是hstore类型。 也许这是hstore的问题,这可能解释了为什么Rails错误输出无法将任何东西放在can't cast ... to因为它不是Rails真正原生理解的数据类型?

编辑2

我刚刚尝试在rails控制台上创建一个新的Presentation ,在开发过程中遇到了完全相同的错误。 我最初的想法是,我可能在search_path遗漏了hstore架构,但添加它并没有好处。

这证实了这不是编写测试的问题,而是实际的编码问题。 我不知道此时该做什么。

我认为你在正确的轨道上,它与将属性保存为hstore数据类型作为预备语句有关。 也许这个答案会对你有帮助。 🙂

https://stackoverflow.com/a/11074481/793330

试试这个:

如果存在,则从spec_helper.rb注释掉下面的行。

 config.order = "random" 

并使用数据库清理程序gem来解决此问题,因为这个问题似乎与运行测试套件的数据有关。

我的Rails应用程序中有相同的错误。 最后我发现它是由以下代码引起的(使用active_model_serializers gem来序列化User的所有属性):

 class UserSerializer < ApplicationModelSerializer attributes *User.attribute_names.map(&:to_sym) end 

我将代码更改为以下内容,然后没有错误:

 class UserSerializer < ApplicationModelSerializer def attributes object.attributes end end 

我还没有找到背后的真正原因。 无论如何希望它有所帮助。