【问题标题】:Is it safe to modify classes for example using "class_eval" (Ruby) in the tests suite?例如在测试套件中使用“class_eval”(Ruby)修改类是否安全?
【发布时间】:2020-06-26 18:32:25
【问题描述】:

换句话说:类修改(在测试中)是否有可能影响生产代码?

(此代码示例使用 Rspec 在 Rails 应用程序中进行测试)

我的控制器示例

在此控制器中创建 ExternalModel。然后调用它的“inscription”方法并将结果分配给一个变量。它将结果用于控制器方法上的其他操作。

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

【问题讨论】:

    标签: ruby-on-rails testing rspec


    【解决方案1】:

    您在这里尝试实现的正是存根的用途:它们实际上是一种在单个示例范围内伪造行为的方法,然后在示例运行后自动重置为其原始行为。

    在您的示例中,大致如下所示:

    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

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 1970-01-01
      • 2016-10-21
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多