小编Bru*_*cca的帖子

具有API和Web视图的Rails 4应用程序中的ActionController :: API

我有一个带有Web视图和JSON API的Rails 4.2.7应用程序。Web视图和API有单独的基本控制器。我希望API基本控制器继承自ActionController::API。但是,在Rails 4中ActionController::API是在rails-apigem中实现的,而我使用的是标准railsgem。

我试图创建一个ActionController::API“克隆”从继承ActionController::Metal和包括所包含所有模块ActionController::API(见源rails-api 在这里rails5 这里)。结果代码为:

class Api::V1::BaseApiController < ActionController::Metal
  include AbstractController::Rendering
  include ActionController::UrlFor
  include ActionController::Redirecting
  # originally ApiRendering
  include ActionController::Rendering
  include ActionController::Renderers::All
  include ActionController::ConditionalGet
  include ActionController::RackDelegation
  # Originally BasicImplicitRender
  include ActionController::ImplicitRender
  include ActionController::StrongParameters
  include ActionController::ForceSSL
  include ActionController::DataStreaming
  # Before callbacks should also be executed as early as possible so
  # also include them at the bottom.
  include AbstractController::Callbacks
  # …
Run Code Online (Sandbox Code Playgroud)

api ruby-on-rails rails-api

7
推荐指数
0
解决办法
607
查看次数

Rails:使用 RSpec 进行测试授权 (Pundit)

我想使用 RSpec 彻底测试 Rails 应用程序授权设置 (Pundit)。

  1. Pundit 文档和其他值得尊敬的来源建议为 Pundit 策略类编写单元测试。这些测试是测试行为(好)还是实施细节(坏)?

  2. 如果我们实际上正在测试行为,那么如果我们最终从 Pundit 切换到另一个授权 gem 或滚动我们自己的授权,我们的测试难道不应该仍然通过吗?

  3. 假设对该authorize方法的调用被意外地从控制器操作中删除,使其开放供公共访问。权威人士的政策测试将不断通过。如果我们没有其他测试涵盖这一点,我们的测试套件可能都是绿色的,而我们的应用程序存在严重的安全漏洞。我们怎样才能避免这种情况呢?也许为 Pundit 控制器类编写单元测试,为控制器单独进行单元测试并模拟authorize控制器测试中的方法以确保调用它们?

编辑:再想一想,我对类的实现细节和公共 API 之间的差异做出了判断。调用特定的公共方法、传递特定的参数并期望特定的返回值是对任何类进行单元测试(和使用)的要求。请忽略第3项,因为我原来的论点是无效的。

  1. 我们可以编写使用不同用户角色登录的控制器或请求规范,调用控制器操作并断言是否授予或拒绝访问,而不是测试 Pundit 策略类。在这种方法中,即使我们切换到另一个授权 gem,测试也会继续通过。此外,如果authorize不调用该方法,它们也会失败。然而,这些将是集成测试,并且应该比单元测试 Pundit 策略类慢。这是否是测试授权设置的更好方法?

提前致谢。

testing tdd rspec ruby-on-rails pundit

5
推荐指数
1
解决办法
2748
查看次数

Rails RSpec、DRY 规范:共享示例与辅助方法与自定义匹配器

我对控制器规范中的每个 HTTP 方法/控制器操作组合重复了一次以下测试:

it "requires authentication" do
  get :show, id: project.id
  # Unauthenticated users should be redirected to the login page
  expect(response).to redirect_to new_user_session_path
end
Run Code Online (Sandbox Code Playgroud)

我找到了以下三种方法来重构它并消除重复。哪一个最合适?

共享示例

在我看来,共享示例是最合适的解决方案。但是,为了将 传递params给共享示例而必须使用块感觉有点尴尬。

shared_examples "requires authentication" do |http_method, action|
  it "requires authentication" do
    process(action, http_method.to_s, params)
    expect(response).to redirect_to new_user_session_path
  end
end

RSpec.describe ProjectsController, type: :controller do
  describe "GET show", :focus do
    let(:project) { Project.create(name: "Project Rigpa") }

    include_examples "requires authentication", :GET, :show do
      let(:params) { {id: project.id} }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

辅助方法 …

ruby rspec ruby-on-rails rspec-rails

5
推荐指数
1
解决办法
1177
查看次数

Rails:在模型规范中测试文件上传验证(Shrine gem)

以下代码使用 RSpec 3.5 和用于文件上传的Shrine gem在 Rails 4.2 应用程序的模型规范内测试图像验证。

我的问题是:

  • 您能想出一种改进以下测试的方法或更好的方法来测试这些验证吗?
  • 如何提高文件大小验证测试的速度?如果可能的话,我想测试它,而无需实际上传>10mb的文件。

文件上传设置的其他方面在控制器和功能规范中进行了测试,这些与此问题无关。

RSpec.describe ShareImage, :type => :model do
  describe "#image", :focus do
    let(:image_file) do
      # Could not get fixture_file_upload to work, but that's irrelevant
      Rack::Test::UploadedFile.new(File.join(
        ActionController::TestCase.fixture_path, 'files', filename))
    end
    let(:share_image) { FactoryGirl.build(:share_image, image: image_file) }
    before(:each) { share_image.valid? }

    context "with a valid image file" do
      let(:filename) { 'image-valid.jpg' }
      it "attaches the image to this record" do
        expect(share_image.image.metadata["filename"]).to eq filename
      end
    end

    context "with JPG extension and …
Run Code Online (Sandbox Code Playgroud)

ruby testing file-upload ruby-on-rails shrine

2
推荐指数
1
解决办法
2857
查看次数

Rails 和 RSpec:使用共享示例测试 CRUD 操作

使用 RSpec 测试多个 Rails 控制器的 RESTful 操作会产生大量代码重复。以下代码是我第一次尝试使用共享示例来解决问题。

这是我不喜欢代码的地方,找不到更好的方法,希望您帮助改进:

  • 共享示例要求let在控制器规范内的块内设置特定变量(高耦合)。我尝试使用模型名称来推断工厂名称并在共享示例中创建测试数据。它可以很好地创建记录和记录变量。但是,某些模型需要存在关联,而 FactoryGirl.attributes_for 不会创建关联记录,因此验证失败。因此,对于不同的模型,valid_attributes 的创建方式不同。我能想到的在共享示例中创建 valid_attributes 的唯一(可能是坏的)方法是传递一个包含用于创建属性的代码的字符串,并在共享示例中对其进行评估(eval)
  • 断言重定向的测试eval用于调用 Rails 的路由/路径助手。此应用程序中的不同控制器具有不同的重定向行为。创建或更新记录后,一些控制器重定向到#show 操作,其他控制器重定向到#index。问题是,当期望重定向到#show, AFAIK 时,我们必须知道记录 ID 才能构建预期的 URL。我们不知道控制器规范中的记录 ID。我们只在共享示例中知道它。那么,如果我们还不知道 URL 是什么(因为我们不知道记录 ID),我们如何将预期的重定向 URL 从控制器规范传递到共享示例?

另外,如果您发现任何其他问题,请告诉我。

控制器规格:

# spec/controllers/quotes_controller_spec.rb
require "rails_helper"

RSpec.describe QuotesController, :focus, :type => :controller do
  login_admin

  let(:model) { Quote }
  let(:record) { FactoryGirl.create(:quote) }
  let(:records) { FactoryGirl.create_pair(:quote) }
  let(:valid_attributes) { FactoryGirl.attributes_for(:quote, quote: "New quote") }
  let(:invalid_attributes) { valid_attributes.update(quote: nil) }

  include_examples "GET #index"
  include_examples "GET #show"
  include_examples "GET #new" …
Run Code Online (Sandbox Code Playgroud)

ruby testing rspec ruby-on-rails

2
推荐指数
1
解决办法
1981
查看次数

在 RSpec 功能规范中测试索引视图排序顺序 (Capybara)

Rails 4.2 应用程序的索引视图有一个表,表头带有排序链接。如果用户单击“电子邮件”标题,记录将按电子邮件排序,依此类推。单击排序链接时,页面将重新加载(使用类似的查询字符串q=email+asc)。尚未使用 AJAX。

我写了以下测试。它有效,但我相信应该有更好的方法来测试它。

it "sorts by e-mail when the 'E-mail' column header is clicked", :focus do
  visit "/admin/users"
  expected_id_order = User.order(:email).map(&:id)
  # Once the page is reloaded (the new sort order is applied), the "stale"
  # class will disappear. Note that due to Turbolinks, only the part of
  # the DOM that is modified by a request will have its elements replaced.
  page.execute_script("$('tr.user:first').addClass('stale')")
  within "thead" do
    click_link("E-mail")
  end
  # Force Capybara to wait until the page …
Run Code Online (Sandbox Code Playgroud)

ruby testing rspec ruby-on-rails capybara

2
推荐指数
1
解决办法
3730
查看次数