【问题标题】:How can I test a method in an API route using rspec?如何使用 rspec 测试 API 路由中的方法?
【发布时间】:2021-10-19 16:50:59
【问题描述】:

我对 ruby​​ 很陌生,我目前正在尝试为 gitlab 贡献一个新功能。我坚持编写一些测试用例。

pages_domains.rb

# frozen_string_literal: true

module API
  class PagesDomains < ::API::Base
    include PaginationParams

    feature_category :pages

    PAGES_DOMAINS_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(domain: API::NO_SLASH_URL_PART_REGEX)
 
    helpers do
      ##### my custom method   #####
      def is_page_domain_verified
        value=false
        result = VerifyPagesDomainService.new(pages_domain).execute
        if(result[:status] == :success)
          value=true
        end  
        value  
      end
      ##### my custom method   #####        
    end
 

    params do
      requires :id, type: String, desc: 'The ID of a project'
    end
    resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
      before do
        require_pages_enabled!
      end

      # other api endpoint logic

      ########## my custom api endpoint logic ############
      desc 'Verify a pages domain' do
        success Entities::PagesDomain
      end
      params do
        requires :domain, type: String, desc: 'The domain'
      end
      get ":id/pages/domains/:domain/verify",requirements: PAGES_DOMAINS_ENDPOINT_REQUIREMENTS do
        authorize! :update_pages, user_project
        if pages_domain.persisted?

          if (is_page_domain_verified==false)
            render_api_error!("Failed to verify domain ownership", :unprocessable_entity)
          end

          present pages_domain, with: Entities::PagesDomain
        else
          render_validation_error!(pages_domain)
        end

      end
      ########## my custom api endpoint logic ############

      # other api enpoint logic
    end
  end
end

pages_domains_spec.rb 中,我添加了失败案例的测试用例,如下所述的代码

pages_domains_spec.rb

  describe 'GET verify for page domain', :focus do
    
    context 'Domain Verifications' do
      it 'returns unprocessable_entity if failed to verify' do
        get api(route_domain_verify, admin)
        expect(response).to have_gitlab_http_status(:unprocessable_entity)
      end
    end  
  end

现在我怎样才能编写成功的测试用例? 为此,我需要从方法is_page_domain_verified 中返回true。我探索了存根,但很难理解它。 我已经尝试使用以下代码来测试使用项目中引用其他人代码的存根

pages_domains_spec.rb

  describe 'GET verify for page domain', :focus do
    
    context 'Domain Verifications' do
      before do
        allow(PagesDomains.is_page_domain_verified).to receive(:get).and_return(true)
      end

      it 'returns ok if verification successful' do
        get api(route_domain_verify, admin)
        expect(response).to have_gitlab_http_status(:ok)
      end
    end  
  end

当我运行它时,我收到了NoMethodError。请帮助编写一个测试用例以获得成功。

Failures:

  1) API::PagesDomains GET verify for page domain Domain Verifications returns ok if verification successful
     Failure/Error: allow(PagesDomains.is_page_domain_verified).to receive(:get).and_return(true)
     
     NoMethodError:
       undefined method `is_page_domain_verified' for PagesDomains:Module
     # ./spec/requests/api/pages_domains_spec.rb:60:in `block (4 levels) in <top (required)>'
     # ./spec/spec_helper.rb:390:in `block (3 levels) in <top (required)>'
     # ./spec/support/sidekiq_middleware.rb:9:in `with_sidekiq_server_middleware'
     # ./spec/spec_helper.rb:381:in `block (2 levels) in <top (required)>'
     # ./spec/spec_helper.rb:377:in `block (3 levels) in <top (required)>'
     # ./lib/gitlab/application_context.rb:31:in `with_raw_context'
     # ./spec/spec_helper.rb:377:in `block (2 levels) in <top (required)>'

Finished in 6.18 seconds (files took 36.48 seconds to load)
1 example, 1 failure

谢谢。

【问题讨论】:

  • 你能在堆栈跟踪/行的顶部添加错误吗?
  • @melcher 请检查我已更新问题并包含堆栈跟踪

标签: ruby-on-rails ruby rspec gitlab gitlab-api


【解决方案1】:

您看到的错误来自PagesDomains.is_page_domain_verified 行,is_page_domain_verified 未在 PagesDomains 类中定义,因为它是一个辅助方法。

我们可以使用控制器助手来存根此方法,但我不确定我是否喜欢这种方法。一种选择是 stub the instancesVerifyPagesDomainService 类。

类似:

allow_any_instance_of(VerifyPagesDomainService).to receive(:execute) and_return({status: :failed})

【讨论】:

    猜你喜欢
    • 2010-12-18
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    相关资源
    最近更新 更多