运行规范时出现的描述性错误,取决于种子
我编写了一个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"}
,分配给properties
。 properties
字段是hstore
类型。 也许这是hstore的问题,这可能解释了为什么Rails错误输出无法将任何东西放在can't cast ... to
因为它不是Rails真正原生理解的数据类型?
编辑2 :
我刚刚尝试在rails控制台上创建一个新的Presentation
,在开发过程中遇到了完全相同的错误。 我最初的想法是,我可能在search_path
遗漏了hstore
架构,但添加它并没有好处。
这证实了这不是编写测试的问题,而是实际的编码问题。 我不知道此时该做什么。
我认为你在正确的轨道上,它与将属性保存为hstore数据类型作为预备语句有关。 也许这个答案会对你有帮助。 🙂
试试这个:
如果存在,则从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
我还没有找到背后的真正原因。 无论如何希望它有所帮助。