如何在Rails测试环境中对模型进行monkeypatch?

时间:2016-03-25 23:38:43

标签: ruby-on-rails rspec capybara

使用案例:在测试Oauth 2提供程序时,OAuth2 :: Client会根据规范进行HTTP调用。

我实现此功能的唯一方法是使用RAILS_ENV=test rails s启动Oauth 2提供程序的第二个实例。

Webmock不能工作,因为我想使用OAuth2 :: Client来测试Oauth 2提供程序来发出HTTP请求,Capybara.run_server = true没有工作,因为它没有响应到HTTP请求。

我想为模型创建一个模拟,类似于RSpec模拟。但是,在启动第二个实例时,它不会加载RSpec模拟(或RSpec,就此而言)。

因此,我找到的解决方案是在第二个实例中加载模型后对其进行monkeypatch。我尝试更改config/environments/test.rb,但在加载模型后我没有找到加载模拟的方法。

那么,在加载所有Rails模型后,在测试环境中加载给定文件的好方法是什么?

Rails 4.1.6

1 个答案:

答案 0 :(得分:1)

使用Railtie。具体而言Railtie::Configuration#after_initialize如果启用了预先加载,或Railtie::Configuration#to_prepare如果每个请求都重新加载模型。

class MyRailtie < Rails::Railtie
  # Executed after Rails is loaded. If Models are
  # eager loaded every model is defined here
  config.to_prepare do
    # Do monkey patching here.
    MyModel # Make sure Model is required
    class MyModel
    end
  end
end

摘要

我要降2美分,希望你不介意。

  1. 在编写集成测试时,您正在限制自己的单元测试边界。
  2. 尝试测试您对系统的期望,而不是您希望它如何进行繁重的工作。
  3. 不必要的限制

    无需尝试避免在集成测试中遇到不同的系统。

    在单元测试中需要使用特定方法和数据进行请求,因为不应该联系系统的其他部分

    在集成测试中,您没有此限制。不需要嘲笑或猴子补丁。您正在测试系统,因为它将在生产中运行。在集成测试中使用模拟实际上会降低测试套件的质量。

    测试实际期望

    我怀疑你不关心OAuth :: Client的作用。您可能不关心OAuth服务器返回的内容。如果您正在使用OAuth和Doorkeeper,那么它们经过了充分测试,无需再次测试它们。

    您可能关心的是能够使用从OAuth提供程序获得的任何令牌访问受保护资源。我们来测试一下。

    即使您正在尝试测试Doorkeeper本身,您也不必关心模型是什么,您可以单独测试模型,测试从服务器返回的实际数据或您希望它如何响应以下请求。