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

时间:2014-02-04 15:04:03

标签: ruby-on-rails ruby rspec capybara

我编写了一个功能规范来测试我的应用程序中的正确多租户行为。它以两个不同的用户身份登录,通过填写表单并将其作为每个用户提交来创建新的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 <top (required)>'

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

./应用程序/控制器/ 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

./规格/特征/ 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

编辑:我检查了测试日志,并在失败的情况下找到 this

  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

此处唯一的哈希值为{"bg_color"=>"#ffffff"},分配给propertiesproperties字段是hstore类型。也许这是hstore的问题,这可能解释了为什么Rails错误输出无法将任何内容置于can't cast ... to之后,因为它不是Rails真正理解的数据类型?

编辑2

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

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

3 个答案:

答案 0 :(得分:1)

我认为您在正确的轨道上认为它与将属性保存到您的hstore数据类型有关。也许这个答案会对你有帮助。 :)

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

答案 1 :(得分:0)

试试这个:

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

config.order = "random"

并使用database cleaner gem来解决此问题,因为此问题似乎与运行测试套件的数据有关。

答案 2 :(得分:0)

我在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

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