Rspec:如何测试每个循环类方法是否被调用?

时间:2019-01-24 22:43:37

标签: ruby-on-rails testing rspec tdd

我目前正尝试在rails worker类中测试部分代码,如下所示(简化版本);

class SenderWorker
   include Sidekiq::Worker
   sidekiq_options :retry => 5

   def perform(current_user_guid)
      Rails.logger.info "Starting for user_guid: #{current_user_guid}"
      user = User.find_by!(guid: current_user_guid)
      team = Team.find_by!(uuid: user.team.uuid)
      profiles = team.profiles 
      profiles.each do |profile|
         SenderClass.new(profile,
                         user).send(User::RECALL_USER)
      end
      Rails.logger.info "Finishing for user_guid: #{current_user_guid}"
   end
end

我编写的测试就是这些,它们正在通过;

context 'when something occurs' do
  it 'should send' do
    sender = double("sender")
    allow(SenderClass).to receive(:new).with(user_profile, current_user) { sender }
    expect(sender).to receive(:send)
    expect(Rails.logger).to receive(:info).exactly(2).times

    worker.perform(user.guid)
  end
end

但是,我并未测试所有电话。有没有一种方法可以确保我测试each do循环中调用的所有内容。预先谢谢你。

1 个答案:

答案 0 :(得分:0)

您可以测试是否收到:send预期的时间。

但是我建议您通过使用类方法封装那些链接的方法来简化测试。像这样:

def self.profile_send(profile, user)
  new(profile, user).send(User::RECALL_USER)
end

然后:

def perform(current_user_guid)
  Rails.logger.info "Starting for user_guid: #{current_user_guid}"
  user = User.find_by!(guid: current_user_guid)
  team = Team.find_by!(uuid: user.team.uuid)
  profiles = team.profiles 
  profiles.each do |profile|
    SenderClass.profile_send(profile, user)
  end
  Rails.logger.info "Finishing for user_guid: #{current_user_guid}"
end

现在您可以测试SenderClass收到:send_profile次X次了。

如果您真的想测试newsend方法调用,则可以为SenderClass.send_profile添加一个测试,但是您可以在循环外对其进行一次测试,并且两个测试都将掩盖您想要的东西。