rspec 在需要存根的私有方法中测试私有方法 [英] rspec test a private method within a private method that needs to be stubbed

查看:60
本文介绍了rspec 在需要存根的私有方法中测试私有方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Simplecov 检测到我在 lib/api_verson.rb 类中遗漏了一些测试:

Simplecov detected that I was missing some tests on my lib/api_verson.rb class:

class ApiVersion

  def initialize(version)
    @version = version
  end

  def matches?(request)
    versioned_accept_header?(request) || version_one?(request)
  end

  private

  def versioned_accept_header?(request)
    accept = request.headers['Accept']
    accept && accept[/application\/vnd\.#{Rails.application.secrets.my_app_accept_header}-v#{@version}\+json/]
  end

  def unversioned_accept_header?(request)
    accept = request.headers['Accept']
    accept.blank? || accept[/application\/vnd\.#{Rails.application.secrets.my_app_accept_header}/].nil?
  end

  def version_one?(request)
    @version == Rails.application.secrets.my_app_default_api_version && unversioned_accept_header?(request)
  end

end

路由文件使用这个类来帮助设置 api 版本:

This class is used by the routes file to help setup api versions:

namespace :api, path: "", defaults: {format: :json} do

scope module: :v1, constraints: ApiVersion.new(1) do
  get '/alive', to: 'api#alive'
end

scope module: :v2, constraints: ApiVersion.new(2) do
  get '/alive', to: 'api#alive'
end

end

此设置移植自 versioning_your_ap_is.

我试图在这里测试 simplecov 报告为失败的方法,现在我陷入了私有方法包含私有方法的情况......

I am trying to test the methods here that simplecov is reporting as failures, and right now I am stuck on the case where the private method contains a private method...

  def version_one?(request)
    @version == Rails.application.secrets.my_app_default_api_version && unversioned_accept_header?(request)
  end

这是我目前的规格:

require 'spec_helper'

describe ApiVersion do

  before(:each) do
    @apiversion = ApiVersion.new(1)
    @current_api_version = Rails.application.secrets.my_app_default_api_version
    @request = ActionController::TestRequest.new(host: 'localhost')
    @request.headers["Accept"] = "application/vnd.#{Rails.application.secrets.my_app_accept_header}-v#{@current_api_version}+json"
  end

  describe "Method #versioned_accept_header? =>" do
    it "Should return false if the header accept variable contains application/vnd.#{Rails.application.secrets.my_app_accept_header}-v#{@current_api_version}+json" do
      expect(@apiversion.send(:unversioned_accept_header?, @request)).to eq(false)
    end
    it "Should return true if no version is included with the header" do
      request = @request
      request.headers["Accept"] = nil
      expect(@apiversion.send(:unversioned_accept_header?, request)).to eq(true)
    end
  end

  describe "Method #version_one? =>" do
    it "test me" do
      # @apiversion.send(:unversioned_accept_header?, @request)

      binding.pry

      # expect(@apiversion.send(:version_one?, @request)).to eq(false)
    end
  end

end

如何存根嵌套的私有方法来测试 version_one 私有方法?

How do I stub the nested private method to test the version_one private method?

推荐答案

以下是我的最终测试和 100% 覆盖率的结果.

Here is how I ended up with my final tests and coverage at 100%.

lib/api_version.rb 文件:

class ApiVersion

  def initialize(version)
    @version = version
  end

  def matches?(request)
    versioned_accept_header?(request) || version_default?(request)
  end

  private

  def versioned_accept_header?(request)
    accept = request.headers['Accept']
    accept && accept[/application\/vnd\.#{Rails.application.secrets.my_app_accept_header}-v#{@version}\+json/]
  end

  def unversioned_accept_header?(request)
    accept = request.headers['Accept']
    accept.blank? || accept[/application\/vnd\.#{Rails.application.secrets.my_app_accept_header}/].nil?
  end

  def version_default?(request)
    @version == Rails.application.secrets.my_app_default_api_version && unversioned_accept_header?(request)
  end

end

跟进所有 rspec 测试:

Followed up by all of the rspec tests:

require 'spec_helper'

describe ApiVersion do

  before(:each) do
    @apiversion = ApiVersion.new(1)
    @current_api_version = Rails.application.secrets.my_app_default_api_version
    @request = ActionController::TestRequest.new(host: 'localhost')
  end

  describe "Method #matches? =>" do
    it "Should return false when the header is not versioned and it's not the header default." do
      @apiversion.stub(:versioned_accept_header?).and_return(false)
      @apiversion.stub(:version_default?).and_return(false)
      expect(@apiversion.matches?(@request)).to eq(false)
    end
    it "Should return true when the proper header has been supplied but is unversioned." do
      @apiversion.stub(:versioned_accept_header?).and_return(true)
      @apiversion.stub(:version_default?).and_return(false)
      expect(@apiversion.matches?(@request)).to eq(true)
    end
    it "Should return true when the proper header has been supplied and is versioned." do
      @apiversion.stub(:versioned_accept_header?).and_return(true)
      @apiversion.stub(:version_default?).and_return(true)
      expect(@apiversion.matches?(@request)).to eq(true)
    end
  end

  describe "Private method #unversioned_accept_header? =>" do
    it "Should return false if the header accept variable contains version 'application/vnd.#{Rails.application.secrets.my_app_accept_header}' in it." do
      @request.headers["Accept"] = "application/vnd.#{Rails.application.secrets.my_app_accept_header}"
      expect(@apiversion.send(:unversioned_accept_header?, @request)).to eq(false)
    end
    it "Should return true if no version is included with the header." do
      @request.headers["Accept"] = nil
      expect(@apiversion.send(:unversioned_accept_header?, @request)).to eq(true)
    end
  end

  describe "Private method #versioned_accept_header? =>" do
    it "Should return true if the header accept variable contains version 'application/vnd.#{Rails.application.secrets.my_app_accept_header}.v#{Rails.application.secrets.my_app_default_api_version}+json' in it." do
      @header = "application/vnd.#{Rails.application.secrets.my_app_accept_header}-v#{Rails.application.secrets.my_app_default_api_version}+json"
      @request.headers["Accept"] = @header
      expect(@apiversion.send(:versioned_accept_header?, @request)).to eq(@header)
    end
  end

  describe "Private method #version_default? =>" do
    it "Should return false when the proper header version is supplied." do
      @apiversion.stub(:unversioned_accept_header?).and_return(false)
      expect(@apiversion.send(:version_default?, @request)).to eq(false)
    end
    it "Should return true when no header is supplied, or a header different than 'application/vnd.#{Rails.application.secrets.my_app_accept_header}' is supplied." do
      @apiversion.stub(:unversioned_accept_header?).and_return(true)
      expect(@apiversion.send(:version_default?, @request)).to eq(true)
    end
  end

end

这篇关于rspec 在需要存根的私有方法中测试私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆