首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用RSpec测试API资源

用RSpec测试API资源
EN

Stack Overflow用户
提问于 2013-08-10 20:54:23
回答 2查看 1.4K关注 0票数 1

我在这个话题上做过一些谷歌搜索,但我仍然很困惑。

我正在使用Zendesk客户端构建一个自定义帮助页面,我正处于需要测试创建ZendeskAPI::Ticket资源的阶段。下面的代码位于spec/features目录中。它使用有效值填充表单,并将表单提交给#create操作。很普通很简单的东西。

代码语言:javascript
复制
require 'spec_helper'

feature 'ticket creation' do
  scenario 'user creates new ticket' do
    visit root_path

    fill_in 'Name', with: 'Billybob Joe'
    fill_in 'Email', with: 'joe@test.com'
    fill_in 'Subject', with: 'Aw, goshdarnit!'
    fill_in 'Issue', with: 'My computer spontaneously blew up!'
    click_button 'Create Ticket'

    expect(page).to have_content('Ticket details')
  end
end

这是售票员的相关部分。ticket_valid?方法为选项哈希提供了最少的验证,clientZendeskAPI::Client的一个实例。

代码语言:javascript
复制
def create
  options = { subject: params[:subject], comment: { value: params[:issue] }, 
              requester: params[:email], priority: 'normal' }
  if ticket_valid? options
    flash[:success] = 'Ticket created.'
    @ticket = ZendeskAPI::Ticket.create(client, options)
    redirect_to ticket_path(@ticket.id)
  else
    flash[:error] = 'Something went wrong. Try again.'
    redirect_to root_url
  end
end

问题是,每当我运行测试时,都会在Zendesk后端创建一个实际的票证,当我只想测试成功的表单提交而不实际创建票证时,就必须手动删除它。

因此,我的问题是,每当我运行测试时,如何测试票证创建表单,而不需要在Zendesk后端创建实际的票证?

我在谷歌上读到的文章和博客模糊地提到了使用RackTest,而其他人则建议在这类事情上根本不使用Capybara,这让我更加困惑。我对RSpec还是比较陌生的,在用API构建Rails应用程序方面我也是比较新的,所以一个清晰的解释将是很棒的。

提前谢谢!!你太棒了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-11 00:17:36

如果您不想调用Zendesk,则必须创建一个"test double“,而不是实际调用。RSpec附带的测试双功能在https://github.com/rspec/rspec-mocks中被描述得最少,但在博客和书籍中有更全面的介绍。

同时发布的答案讨论了创建单独的类,但仍然涉及创建Zendesk票证。实际上,您不需要单独的类,也不需要创建任何ZendeskAPI对象。相反,您需要使用存根ZendeskAPI::Ticket#create来返回一个测试双,这反过来需要提供您的测试所需的任何Zendesk票证方法,其中至少包括id

凯巴拉的使用实际上是一个次要的问题,涉及到你如何驾驶测试。但是请注意,您的测试当前需要呈现票证页并检查该页的内容。如果您想测试“只是”您的控制器,那么您可以/应该只测试它是否进行了正确的调用(例如,对ZendeskAPI::Ticket)并重定向到适当的页面。此外,如果您这样做,您有更少的模拟在您的测试双。

票数 0
EN

Stack Overflow用户

发布于 2013-08-11 00:17:21

一种方法是将ZenDesk接口抽象到您自己的类中,然后在测试中对其进行模拟。

例如,您可以创建一个接口类:

代码语言:javascript
复制
class ZendeskGateway

  def create_ticket(client, options)
    ZendeskAPI::Ticket.create(client, options)
  end

end

然后,在代码中,用接口类替换控制器中Zendesk API的用法:

代码语言:javascript
复制
class TicketsController < ApplicationController

  attr_accessor :zendesk_gateway

  after_initialize :init

  def init
    @zendesk_gateway = ZendeskGateway.new
  end 

  def create
    options = { subject: params[:subject], comment: { value: params[:issue] }, 
                  requester: params[:email], priority: 'normal' }
    if ticket_valid? options
      flash[:success] = 'Ticket created.'

      @ticket = @zendesk_gateway.create_ticket(client, options)

      redirect_to ticket_path(@ticket.id)
    else
      flash[:error] = 'Something went wrong. Try again.'
      redirect_to root_url
    end

  end

end

现在它已经抽象了,您可以使用模拟框架(如摩卡咖啡)在测试期间对方法进行存根,这样它就不会真正调用Zendesk:

代码语言:javascript
复制
zendesk_ticket = ZendeskAPI::Ticket.new(client, :id => 1, :priority => "urgent")

@controller.zendesk_gateway.expects(:create_ticket).returns(zendesk_ticket)

这是一个非常迅速/肮脏的例子。但希望你能看到一般的想法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18166257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档