簡體   English   中英

修改類是否安全,例如在測試套件中使用“class_eval”(Ruby)?

[英]Is it safe to modify classes for example using “class_eval” (Ruby) in the tests suite?

換句話說: class 修改(在測試中)是否有可能影響生產代碼?

(此代碼示例使用 Rspec 在 Rails 應用程序中進行測試)

我的 controller 示例

在此 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM