测试整个 Rspec 测试套件失败

6
我有一个奇怪的情况,如果我运行单个rspec模型spec文件,则所有示例都是绿色的;如果我测试整个spec/models文件夹,则所有示例也都是绿色的。如果我测试控制器,它们也都通过了。但如果我测试整个套件(通过rspec spec),那么我会得到失败的结果——如果我完全删除控制器测试,则所有内容都是绿色的。现在我预计这完全是自己造成的问题,但我就是想不出来。
我已经将问题缩小到控制器测试中的特定示例,这些示例会导致模型规范中的示例失败。
例如,在notes_controller_spec.rb中,如果存在以下行:
 Note.any_instance.stubs(:valid?).returns(false)

这导致我的models/account_spec.rb出现故障。

Failure/Error: @account.all_notes.should have(2).notes
ArgumentError:
comparison of Note with Note failed
./app/models/account.rb:293:in `sort'

293行在哪里;

 (self.notes + self.transactions.map(&:notes).flatten).sort {|a,b| a.created_at <=> b.created_at }

我非常确定这将是那种让人扇自己脸的时刻,所以请对我温柔点!


created_at 可能为其中一个笔记的 nil,这意味着您的排序块将会比较 nilFixnum,这将导致该块返回 nil,从而使排序出现您所看到的 ArgumentError。您确定在运行此行时所有实例都已保存在数据库中吗?是否可能在每个示例运行之前未清空您的数据库? - Rob Davis
我遇到了类似的问题。我有一种感觉它可能与这个rspec问题有关(https://github.com/rspec/rspec-mocks/issues/54),尽管它声称已经被修复了。 - stephan.com
我正在为模型的任何实例存根方法 - 这是一组特定测试中要测试的不同模型。当我运行需要该方法的另一组测试时,它找不到该方法。在一个文件中删除测试中的存根使另一个文件通过。真的很烦人。我一直在尝试安装不同版本的rspec进行实验。 - stephan.com
这是我的问题概要:https://gist.github.com/1111833 - stephan.com
这个存根是在 before :all 块中完成的吗?这可能会导致方法保持存根的问题。只是猜测。 - siannopollo
我在rails 4.1、rspec 3和feature specs中遇到了类似的问题。在我的情况下,这是一个日期问题,但我不知道该如何解决它。在fixture中,我有一个日期列,其值为"1.day.ago.to_s(:db)"。然后在我的spec中,我做了类似于"expect(page).to have_content(1.day.ago.to_date)"的操作,但它失败了,因为spec中的"1.day.ago"比fixture中的早一天。它只在运行完整套件时失败。更糟糕的是,在某些时间段它不会失败,让我觉得这与时区有关。我不明白。 - François
3个回答

1
你在 before :all 块中设置日期了吗?这些不是事务性的,可能会导致测试污染问题。
另外,我认为你的语法可能有误:
    Note.any_instance.stubs(:valid?).returns(false)

应该是:

    Note.any_instance.stub(:valid?).and_return(false)

0

我在使用 RSpec 3 和 Rails 4.1 时遇到了类似的问题。每当我单独运行有问题的 spec 文件时,它都会通过,但是运行整个测试套件会导致它失败。

在我的情况下,这与时区有关。我在 ApplicationController 中明确设置了时区,但由于某种原因,我的 feature specs 不喜欢它。如果我在测试环境中不设置时区,一切都会再次通过。例如:

unless Rails.env.test?
  Time.zone = "some timezone value here"
end

0
我曾经遇到过类似的问题:单独运行模型规范测试时,一切正常。但是当我运行整个模型套件时,大约有30个失败。我所做的是查看所有失败发生之前的文件。在那里,我发现我正在线程内设置东西并使用default_scopes,就像这个railscast中所示。
在before子句中,我打印了Company.current_id。正如我所想的那样,当单独运行时,Company.current_idnil。当运行套件时,Company.current_id2。这就是使用默认作用域时会发生的情况。为了解决这个问题,我只需在before子句中将Company.current_id设置为nil即可。
Before
describe Service, type: :model do
  before do
  end
end

之后

describe Service, type: :model do
  before do
    Company.current_id = nil
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接