Rails 已初始化 ActiveRecord 对象的存根方法
Rails stub method on initialized ActiveRecord object
我想存根 set_user_tokens
,它在初始化(未保存)的 ActiveRecord 对象上执行。此方法将标记分配给 login
对象。
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
所以我想存根 setu_user_tokens
方法:
login.set_user_tokens(aware_response) if set_token
接收具有 oauth_tokens
属性的登录 ActiveRecord 对象,如下所示:
login.oauth_token
=> {"access_token" => return_token,"refresh_token" => nil,"token_expiration" => 1200 }
我试过:
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 },
)
但是我收到一个错误:
Login does not implement #set_user_tokens
我敢打赌你的问题 set_user_tokens
是 AwareAuth
的一部分。
由于您仅将此模块作为 AwareLogin#authenticate!
方法的一部分包含在实例 (login
) 的特征 class 中,因此 Login
class 不会在任何时间点实现该方法。
您这样做是否有原因,而不是首先将 AwareAuth
包含在 Login
class 中?
无论哪种方式,虽然您的问题似乎缺乏测试本身的上下文,但如果我理解正确,我们应该能够按如下方式解决这些问题:
it 'sets user tokens' do
login = Login
.find_or_initialize_for_authentication('some_email@example.com', 'aware')
.tap {|l| l.singleton_class.send(:include, AwareAuth) }
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
通过使用部分双打,您可以存根您需要的特定方法,而不会影响对象本身的任何其他功能。
我想存根 set_user_tokens
,它在初始化(未保存)的 ActiveRecord 对象上执行。此方法将标记分配给 login
对象。
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
所以我想存根 setu_user_tokens
方法:
login.set_user_tokens(aware_response) if set_token
接收具有 oauth_tokens
属性的登录 ActiveRecord 对象,如下所示:
login.oauth_token
=> {"access_token" => return_token,"refresh_token" => nil,"token_expiration" => 1200 }
我试过:
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 },
)
但是我收到一个错误:
Login does not implement #set_user_tokens
我敢打赌你的问题 set_user_tokens
是 AwareAuth
的一部分。
由于您仅将此模块作为 AwareLogin#authenticate!
方法的一部分包含在实例 (login
) 的特征 class 中,因此 Login
class 不会在任何时间点实现该方法。
您这样做是否有原因,而不是首先将 AwareAuth
包含在 Login
class 中?
无论哪种方式,虽然您的问题似乎缺乏测试本身的上下文,但如果我理解正确,我们应该能够按如下方式解决这些问题:
it 'sets user tokens' do
login = Login
.find_or_initialize_for_authentication('some_email@example.com', 'aware')
.tap {|l| l.singleton_class.send(:include, AwareAuth) }
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
通过使用部分双打,您可以存根您需要的特定方法,而不会影响对象本身的任何其他功能。