Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby RSpec如何剔除收益率并使其不受影响_Ruby_Unit Testing_Rspec_Rspec Rails - Fatal编程技术网

Ruby RSpec如何剔除收益率并使其不受影响

Ruby RSpec如何剔除收益率并使其不受影响,ruby,unit-testing,rspec,rspec-rails,Ruby,Unit Testing,Rspec,Rspec Rails,我有一个环绕动作,叫做set\u current\u user def set_current_user CurrentUser.set(current_user) do yield end end 在当前用户单例中 def set(user) self.user = user yield ensure self.user = nil end 我不知道如何剔除收益率,而不调用方法的Survey部分 理想情况下,我想做一些像 it 'sets

我有一个环绕动作,叫做
set\u current\u user

def set_current_user
  CurrentUser.set(current_user) do
    yield
  end
end
在当前用户单例中

  def set(user)
    self.user = user
    yield
  ensure
    self.user = nil
  end
我不知道如何剔除收益率,而不调用方法的Survey部分

理想情况下,我想做一些像

it 'sets the user' do
  subject.set(user)
  expect(subject.user).to eql user
end 
我犯了两个错误

  • 没有给出任何块
  • 当我传递一个块时,调用
    self.user=nil

提前感谢

以下几点可能会有所帮助:

确保为无论发生什么情况都要运行的代码块保留
,因此您的
self.user
将始终为
nil
。我认为如果出现异常,您需要将用户分配到nil。在这种情况下,您应该改用
rescue

def set(user)
  self.user = user
  yield
rescue => e
  self.user = nil
end
至于单元测试,您希望只测试
CurrentUser
类中的
.set
方法。假设您已将所有内容正确地连接到around筛选器中,下面是一个可能适合您的示例:

describe CurrentUser do
  describe '.set' do
    let(:current_user) { create(:user) } 
    subject do
      CurrentUser.set(current_user) {}
    end
    it 'sets the user' do
      subject
      expect(CurrentUser.user).to eq(current_user)
    end 
  end
end

希望这有帮助

我没有提到我需要在每次请求后清除用户

这就是我想到的。将期望放在lambda中有点疯狂,但确实确保在处理请求之前设置用户,并在处理请求之后清除用户

describe '.set' do
  subject { described_class }

  let(:user) { OpenStruct.new(id: 1) }

  let(:user_expectation) { lambda{ expect(subject.user).to eql user } }

  it 'sets the user prior to the block being processed' do
    subject.set(user) { user_expectation.call }
  end

  context 'after the block has been processed' do
    # This makes sure the user is always cleared after a request
    # even if there is an error and sidekiq will never have access to it.

    before do
      subject.set(user) { lambda{} }
    end

    it 'clears out the user' do
      expect(subject.user).to eql nil
    end
  end
end

我不确定您打算用它完成什么,因为您似乎只是想确保
user
在块中设置,然后取消设置。如果是这样的话,那么下面的方法就可以了

class CurrentUser
  attr_accessor :user
  def set(user)
    self.user = user
    yield
  ensure
    self.user = nil
  end
end

describe '.set' do
  subject { CurrentUser.new }
  let(:user) { OpenStruct.new(id: 1) }
  it 'sets user for the block only' do 
    subject.set(user) do 
      expect(subject.user).to eq(user)
    end 
    expect(subject.user).to be_nil 
  end
end
这将检查块内(调用yield的地方)的
subject.user
是否等于
user
,之后的
subject.user
是否为零

输出

.set
  sets user for the block only

Finished in 0.03504 seconds (files took 0.14009 seconds to load)
1 example, 0 failures

感谢您的回复,我没有提到我需要在每次请求后清除用户。我在下面发布了一个答案,我承认这有点奇怪,但确实完成了任务。方法中可以使用
block\u given?
方法来判断是否提供了块。