Rspec和commit回调给出错误的结果

时间:2018-01-26 23:58:25

标签: rspec ruby-on-rails-5

我有一个用户和角色模型:

class User < ApplicationRecord

  has_and_belongs_to_many :roles
  validates :roles, presence: true, on: :save
  after_create_commit :assign_role

  private

  def assign_role
    self.roles << Role.client if roles.empty?
  end
end

class Role < ApplicationRecord

  has_and_belongs_to_many :users
  validates :name, presence: true, uniqueness: true
  scope :client, -> { where(name: :client) }
end

我无法通过以下Rspec:

  describe '#assign_role' do
    context 'when creating a new user' do
      it 'is triggered', test: true do
        user = build(:user)
        expect(user).to receive(:assign_role)
        user.run_callbacks(:commit)
      end
    end
  end
(#<User id: nil, email: "tester1@example.com", created_at: nil, updated_at: nil>).assign_role(*(any args))
 expected: 1 time with any arguments
 received: 0 times with any arguments

我知道这个方法是被调用的因为我把binding.pry放在方法中。

但是如果我将模型中的回调更改为after_create并且:在rspec测试中创建它可以正常工作

describe '#assign_role' do
    context 'when creating a new user' do
      it 'is triggered', test: true do
        user = build(:user)
        expect(user).to receive(:assign_role)
        user.run_callbacks(:create)
      end
    end
  end

我甚至尝试使用self.use_transactional_tests = false关闭事务测试,但它不会更改结果。 我想使用after_create_commit而不是after_create。

如何让这个测试通过?

rspec 3.7,rails 5.2.beta2

1 个答案:

答案 0 :(得分:0)

请试试这个宝石 gem "test_after_commit"为此,你可能会想,“这很奇怪。为什么我必须使用一个完整的独立gem来测试Rails附带的回调?它不应该自动发生吗?“

你是对的。真奇怪。但它不会长久保持怪异。

一旦Rails 5更新,您就不必担心test_after_commit

please see this link