2

当请求规范失败(错字或其他异常)时,我们目前面临一个问题,它会影响实际上应该不受影响的其他请求规范。问题是我们使用了很多 gem,所以我尝试创建一个最小的复制应用程序(没有成功,https://github.com/tak1n/reproduction

问题详细:

我们有一个请求规范,我们需要在其中登录用户。对于用户身份验证,我们使用设计,因此我们使用 Warden::Test::Helpers 在请求规范中登录用户。当用户登录时,Devise 会自动更新一些与用户相关的属性(last_sign_in_at、last_sign_in_ip 等)。

这里的问题是,当它尝试保存用户以进行此更改时,最终结果是 INSERT INTO 用户而不是 UPDATE 用户,因此它崩溃了。

这是我们应用程序的示例规范:

require 'rails_helper'

RSpec.describe 'Suggestions API' do
  let(:user) { FactoryGirl.create(:user, :professional) }

  before do
    login(user) # same as in https://github.com/tak1n/reproduction/blob/master/spec/support/request_macros.rb#L6
  end

  describe '/suggestions.json', :vcr do
    context 'with non saved filter' do
      # some setup stuff here (setup proper objects in db)

      # also params are defined here through let(:params) { ... }

      it 'returns proper suggestions' do
        Suggestion.refresh!

        get '/suggestions.json', paramst

        expect(json.count).to eq(2)

        expect(json.first['id']).to eq(sug2.id)
        expect(json.second['id']).to eq(sug1.id)
      end
    end

    context 'with saved filter' do
      # some setup stuff here (setup proper objects in db)

      # also params are defined here through let(:params) { ... }

      it 'returns proper suggestions' do
        Suggestion.refresh!

        get '/suggestions.json', params

        expect(json.count).to eq(2)

        expect(json.first['id']).to eq(sug2.id)
        expect(json.second['id']).to eq(sug1.id)
      end
    end
  end
end

这样做的结果应该是第一个规范由于错字而失败paramst,它确实如此,但它也影响了第二个规范:

这是规范运行:https ://gist.github.com/tak1n/102c1aa121b66e0ab56602b76f911ec0

我试图深入挖掘并看到 save 创建或更新记录的逻辑取决于https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb#L85

接下来,我尝试输出@new_record这种情况下的内容。

def new_record?
  sync_with_transaction_state
  puts "New record: #{@new_record}" if self.class == User
  @new_record
end

我得到了关注:https ://gist.github.com/tak1n/330560a3a108abc8fce4d105a48ac444

当规范以不同的顺序运行时(先不失败,然后规范有错字或异常),我得到了这个:https ://gist.github.com/tak1n/6eb24693226d8e6a713c0865ea1bebd5

这里的区别在于“工作”规范运行New Record: <boolean>不同。当带有异常的规范在它之前运行时,新记录突然变为真,因此它会生成 SQL 来创建新记录。

接下来我假设一些宝石导致了这个问题,很可能我认为它会是 database_cleaner 但在复制中我或多或少地做同样的事情并且它在那里工作。

问题是我真的被困在调试中,不知道从哪里开始。此外,我不确定是哪个 gem 或我们的代码本身导致了这种情况。

如果您需要更多详细信息,请随时提出任何问题,在此先感谢。

4

1 回答 1

0

似乎问题是由设计异步(https://github.com/mhfs/devise-async)引起的。

有关更多信息,请参阅https://github.com/rails/rails/issues/26038https://github.com/mhfs/devise-async/issues/96

于 2016-08-04T07:07:11.600 回答