![](/img/trans.png)
[英]When using class_eval in ruby, how to access the constant in the original class?
[英]Is it safe to modify classes for example using “class_eval” (Ruby) in the tests suite?
換句話說: class 修改(在測試中)是否有可能影響生產代碼?
(此代碼示例使用 Rspec 在 Rails 應用程序中進行測試)
在此 controller ExternalModel 被創建。 然后調用它的“inscription”方法並將結果分配給一個變量。 它將結果用於 controller 方法的其他操作。
class ExampleController < ApplicationController
def callback_page
external_model = ExternalModel.new(argument)
result = external_model.inscription
render_error_json && return unless result['error_desc'].eql? 'OK'
TransactionModel.create(token: result['token'])
end
end
在規范中,我修改了 ExternalModel 以便在調用 .inscription 方法時返回我想要的內容:
ExternalModel.class_eval {
def inscription(_fake_arguments)
{
'error_desc' => 'OK',
'token' => '1234'
}
end
}
這是整個規范:
RSpec.describe 'Example management', type: :request do
context 'callback_page' do
it 'creates a transaction' do
ExternalModel.class_eval {
def inscription(_fake_arguments)
{
'error_desc' => 'OK',
'token' => '1234'
}
end
}
expect {
post(callback_page_path)
}.to change(TransactionModel.all, :count).by(1)
expect(response).to render_template(:callback_page)
end
end
end
您在這里嘗試實現的正是存根的用途:它們實際上是一種在單個示例的 scope 中偽造行為的方法,然后在示例運行后自動重置為其原始行為。
在您的示例中,這大致如下所示:
allow_any_instance_of(ExternalModel).
to receive(:inscription).
and_return({ 'error_desc' => 'OK', 'token' => '1234' })
更多詳細信息可以在 rspec-mocks gem 的文檔中找到: https://relishapp.com/rspec/rspec-mocks/v/3-9/docs 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.