【问题标题】:rspec stack level too deeprspec 堆栈级别太深
【发布时间】:2012-03-04 01:27:50
【问题描述】:

当我分别运行我的模型规格和控制器规格时,这很好。当我一起运行它们时,我得到一个堆栈溢出,字面意思:)

$ bundle exec rspec --fail-fast spec/models
........

Finished in 0.44274 seconds
8 examples, 0 failures

$ bundle exec rspec --fail-fast spec/controllers
..

Finished in 0.99339 seconds
2 examples, 0 failures

$ bundle exec rspec --fail-fast spec
F

Failures:

  1) HerpController derp derp example
     Failure/Error: Unable to find matching line from backtrace
     SystemStackError:
       stack level too deep
     # /Users/jared/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.2.1/lib/abstract_controller/layouts.rb:359

Finished in 0.02241 seconds
1 example, 1 failure

我什至如何开始调试呢?谢谢。

【问题讨论】:

  • 我会随机删除一半的控制器/型号规格,看看问题是否仍然存在。如果是这样,请删除更多控制器规格。如果没有,则恢复您删除的规范并删除最初保留的规范。重复直到您将范围缩小到一组特定的规格

标签: ruby-on-rails ruby rspec


【解决方案1】:

如果你正在检查一些实际上没有初始化的变量,你可能会得到“无法从回溯中找到匹配的行”错误

在这个例子中,注意 var observation 没有在 wrong sn-p

中初始化

错误的 sn-p

describe "GET index" do
  it "assigns all observations as @observations" do
    get :index, {}, valid_session
    assigns(:observations).should eq([observation])
  end
end

固定示例(第 3 行)

describe "GET index" do
  it "assigns all observations as @observations" do
    observation = Observation.create! valid_attributes
    get :index, {}, valid_session
    assigns(:observations).should eq([observation])
  end
end

有时我们依赖使用 let 作为初始化器,但忘记添加它,例如

let(:observation) {FactoryGirl.create(:observation)}

【讨论】:

    【解决方案2】:

    一次删除我的一半规格出现了问题。我想这是一个平分调试的例子。感谢 Frederick Cheung,他的评论提出了这种方法。

    对于后代来说,这就是问题所在。

    include Rails.application.routes.url_helpers
    describe "Attendee#next_page" do
    end
    

    显然,包括进入describe

    describe "Attendee#next_page" do 
      include Rails.application.routes.url_helpers
    end
    

    我有很多关于 rspec 的知识要学习。 :)

    【讨论】:

    【解决方案3】:

    我会在代码中的关键点使用putsraise 语句开始,这样您就可以开始缩小导致问题的行。一旦你开始接近,你可以一次注释掉一行来找出问题消失的那一行——一旦你把它降到一行,你就可以弄清楚那一行在做什么而 Ruby 没有不喜欢。

    一般而言,“堆栈级别太深”通常是一个无限循环或无限递归问题 - 我认为模型正在调用正在调用模型的控制器,或者反之亦然-反之亦然。在您开始注释行之前无法确定,但是您有函数调用的任何地方都将属于您的可疑短名单。祝你好运!

    【讨论】:

      【解决方案4】:

      您可以在代码中添加debugger 语句并以这种方式进行调试,或者在您知道正在运行的代码位置开始使用puts "got here"。我建议也使用有意义的东西而不是“到达这里”:-)

      【讨论】:

      • 这个puts 技术也是我使用的,我不得不说它是有史以来最被低估的调试方式!
      猜你喜欢
      • 2013-10-05
      • 2016-09-10
      • 2015-04-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2012-07-24
      相关资源
      最近更新 更多