简体   繁体   English

初始化 ActiveRecord object 上的 Rails 存根方法

[英]Rails stub method on initialized ActiveRecord object

I want to stub set_user_tokens which is executed on the initialized (not saved) ActiveRecord object.我想存根set_user_tokens ,它在初始化(未保存)ActiveRecord object 上执行。 This method assigns a token to the login object.此方法将令牌分配给login object。

class AwareLogin < Authenticatable
  def authenticate!
      login = Login.find_or_initialize_for_authentication(params[:login][:email], 'aware')
      class << login
        include AwareAuth
      end

      if login.valid_password?(password) || (set_token = login.id.nil? && aware_response.success?)
        login.set_user_tokens(aware_response) if set_token
        success!(login)
      else
        aware_response.success? ? fail!(:aware_auth) : raise(ActiveRecord::Rollback)
      end
    end
  end
end

So I want to stub setu_user_tokens method:所以我想存根setu_user_tokens方法:

    login.set_user_tokens(aware_response) if set_token

to receive login ActiveRecord object with attributes of oauth_tokens like below:接收登录 ActiveRecord object 与oauth_tokens属性如下:

login.oauth_token
=> {"access_token" => return_token,"refresh_token" => nil,"token_expiration" => 1200 }

I've tried:我试过了:

      allow_any_instance_of(Login).to receive(:set_user_tokens).with(status: 200, body: { access_token: return_token }.to_json, success?: true).and_return(
        oauth_tokens: {
          "access_token" => return_token,
          "refresh_token" => nil,
          "token_expiration" => 1200 },
      )

But I'm getting an error:但我收到一个错误:

Login does not implement #set_user_tokens登录没有实现#set_user_tokens

I would be willing to bet your issue is set_user_tokens is part of AwareAuth .我愿意打赌你的问题是set_user_tokensAwareAuth的一部分。

Since you are only including this module in the eigenclass of the instance ( login ) as part of the AwareLogin#authenticate!由于您仅将此模块包含在实例的特征类 ( login ) 中,作为AwareLogin#authenticate! method, the Login class does not implement that method at any point in time.方法, Login class 在任何时间点都不会实现该方法。

Is there a reason you are doing it this way rather than just including AwareAuth in the Login class in the first place?您这样做是否有原因,而不是首先在Login class 中包含AwareAuth

Either way, while your question appears to lack context for the test itself, if I understand correctly, we should be able to resolve these issues as follows:无论哪种方式,虽然您的问题似乎缺乏测试本身的背景,但如果我理解正确,我们应该能够解决这些问题,如下所示:

let(:login) do   
  Login
   .find_or_initialize_for_authentication('some_email@example.com', 'aware')
   .tap {|l| l.singleton_class.send(:include, AwareAuth) }
end 

it 'sets user tokens' do 
  allow(Login).to receive(:find_or_initialize_for_authentication).and_return(login) 
  allow(login).to receive(:set_user_tokens).and_return(
        oauth_tokens: {
          "access_token" => return_token,
          "refresh_token" => nil,
          "token_expiration" => 1200 },
      )
  #perform your action and expectations here
end

By using partial doubles you can stub the specific methods you need to without impacting any other functionality of the object itself.通过使用部分双打,您可以存根您需要的特定方法,而不会影响 object 本身的任何其他功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM