RSpec控制器ajax请求测试

RSpec控制器ajax请求测试,ajax,ruby-on-rails-3,rspec2,Ajax,Ruby On Rails 3,Rspec2,我正在测试我的控制器,但请求是通过ajax发出的。我不知道如何处理这个问题。我正在尝试类似HTTP请求的方式,但我在HTTP请求之前使用XHR。但是当我运行测试时,我看到了这个问题 1) RwsController Update widget score takes widget rate information Failure/Error: mock_widget.should_receive(:update_attributes).with({'these' => 'para

我正在测试我的控制器,但请求是通过ajax发出的。我不知道如何处理这个问题。我正在尝试类似HTTP请求的方式,但我在HTTP请求之前使用XHR。但是当我运行测试时,我看到了这个问题

1) RwsController Update widget score takes widget rate information
     Failure/Error: mock_widget.should_receive(:update_attributes).with({'these' => 'params'})
       (Mock "Widget_1003").update_attributes({"these"=>"params"})
           expected: 1 time
           received: 0 times
     # ./spec/controllers/rws_controller_spec.rb:28:in `block (3 levels) in <top (required)>'
1)RwsController更新小部件分数获取小部件速率信息
失败/错误:mock_小部件。应_接收(:更新_属性)。使用({'this'=>'params'))
(模拟“Widget_1003”)。更新_属性({“this”=>“params”})
预计:1次
收到:0次
#./spec/controllers/rws\u controller\u spec.rb:28:in“块(3级)in”
我有一个控制器,所有的ajax请求都在这里记录DB

class RwsController < ApplicationController
  layout 'widget'
  skip_before_filter :verify_authenticity_token, :only => [:edit, :update, :show, :getUserInfo]
  respond_to :js, :json, :html

  #cookie check and show exact view
  def show
    @widget = Widget.find_by_uuid(params[:uuid])
    if cookies["last_widget_id"] == @widget.uuid
      render :action => "generate"
    end
    @widget = Widget.find_by_uuid(params[:uuid])
  end

  def edit
    @widget = Widget.find_by_uuid(params[:uuid])
  end

  #after rating the rates and other details record on DB
  def update
    @widget = Widget.find_by_uuid(params[:uuid])
    #logger.info("score-in:  " + params[:score])
    @widget.score = params[:score].to_i
    @widget.total_score = params[:total_score].to_i
    @widget.click_number = params[:click_number].to_i
    @widget.average = params[:average].to_i
    #set cookie
    cookies[:last_widget_id] = {:value => @widget.uuid, :expires => 1.year.from_now}
    @widget.save!
    render :text => 'ok'
    logger.info("score-out:  " + @widget.score.to_s)
    logger.info("cookie-id:  " +  cookies[:last_widget_id])
  end

  #iframe creates and calls .js.erb file
  def generate
    @widget = Widget.find_by_uuid(params[:uuid])
    #@widget_id = @widget.id
    respond_to do |format|
      format.js {}
    end
  end

  #recording the visitor who visit the page
  def getUserInfo
    data = params[:mainURL]
    data1 = params[:mainBrowserAgent]
    data2 = params[:mainReferer]
    data3 = params[:mainDisplayInfo]
    data4 = params[:currentWidgetId]
    @widgetTraffic = WidgetTraffic.new(params[:widget_traffic])
    @widgetTraffic.widget_id = @widget_id
    @widgetTraffic.main_url = data
    @widgetTraffic.main_browser = data1
    @widgetTraffic.main_referer = data2
    @widgetTraffic.main_display = data3
    @widgetTraffic.widget_id = data4


    @widgetTraffic.save!
    render :text => 'ok'
  end
end
class RwsController[:编辑,:更新,:显示,:getUserInfo]
回复:js,:json,:html
#cookie检查并显示精确视图
def秀
@widget=widget.find_by_uuid(参数[:uuid])
如果cookies[“最后一个小部件\u id”]==@widget.uuid
呈现:操作=>“生成”
结束
@widget=widget.find_by_uuid(参数[:uuid])
结束
定义编辑
@widget=widget.find_by_uuid(参数[:uuid])
结束
#在对费率和其他详细信息进行评级后,记录在DB上
def更新
@widget=widget.find_by_uuid(参数[:uuid])
#logger.info(“分数输入:”+params[:分数])
@widget.score=params[:score].to_i
@widget.total_score=params[:total_score].to_i
@widget.click_number=params[:click_number].to_i
@widget.average=params[:average].to_i
#设置cookie
cookies[:last\u widget\u id]={:value=>@widget.uuid,:expires=>1.year.from\u now}
@widget.save!
呈现:text=>“确定”
logger.info(“得分:”+@widget.score.to_s)
logger.info(“cookieid:+cookies[:last\u widget\u id])
结束
#iframe创建并调用.js.erb文件
def生成
@widget=widget.find_by_uuid(参数[:uuid])
#@widget_id=@widget.id
回应待办事项|格式|
format.js{}
结束
结束
#记录访问页面的访问者
def getUserInfo
数据=参数[:mainURL]
数据1=参数[:mainBrowserAgent]
数据2=参数[:mainReferer]
数据3=参数[:main displayinfo]
数据4=参数[:currentWidgetId]
@widgetTraffic=widgetTraffic.new(参数[:widget\u流量])
@widgetTraffic.widget\u id=@widget\u id
@widgetTraffic.main_url=数据
@widgetTraffic.main_browser=data1
@widgetTraffic.main\u referer=data2
@widgetTraffic.main_display=data3
@widgetTraffic.widget_id=data4
@widgetTraffic,救命!
呈现:text=>“确定”
结束
结束
所有场景都是用户访问侧边并单击包含一些信息(如分数和其他信息)的链接,ajax将数据发送到控制器,以将其保存为您在控制器中看到的内容


但我不能解决它吗?如何更新?

您的更新方法在不使用更新属性的情况下更新@widget对象:

 def update
    @widget = Widget.find_by_uuid(params[:uuid])
    #logger.info("score-in:  " + params[:score])
    @widget.score = params[:score].to_i
    @widget.total_score = params[:total_score].to_i
    @widget.click_number = params[:click_number].to_i
    @widget.average = params[:average].to_i
    #set cookie
    cookies[:last_widget_id] = {:value => @widget.uuid, :expires => 1.year.from_now}
    @widget.save!
但是,您的更新测试要求您调用 @widget.update_属性(参数)


我认为最有可能的是,最初的update方法确实调用了update_属性,然后对代码进行了修改。这就是测试失败的原因。

您的更新方法更新@widget对象,而不使用update\u属性:

 def update
    @widget = Widget.find_by_uuid(params[:uuid])
    #logger.info("score-in:  " + params[:score])
    @widget.score = params[:score].to_i
    @widget.total_score = params[:total_score].to_i
    @widget.click_number = params[:click_number].to_i
    @widget.average = params[:average].to_i
    #set cookie
    cookies[:last_widget_id] = {:value => @widget.uuid, :expires => 1.year.from_now}
    @widget.save!
但是,您的更新测试要求您调用 @widget.update_属性(参数)


我认为最有可能的是,最初的update方法确实调用了update_属性,然后对代码进行了修改。这就是测试失败的原因。

我的答案解决了你的问题吗?我的答案解决了你的问题吗?我修复了我的规范控制器,比如,描述“更新小部件分数”做它“获取小部件速率信息”做WidgetTraffic.stub(:new)。使用({this'=>'params'){mock_小部件_流量(:save=>true)}xhr:put,:Update,:widget\u traffic=>{'this'=>'params'}assigns(:widget\u traffic)=@mock\u widget\u traffic response.should应该是\u success end end但是我在这次看到了这些错误,1)RwsController Update widget score获取widget速率信息失败/错误:put:Update,id:@widget,widget:Factory.attributes\u for(:widget)NoMethodError:undefined method
score='for nil:NilClass#./app/controllers/rws_controller.rb:23:in
update'./spec/controllers/rws_controller_spec.rb:34:in`block(3层)in',这意味着Widget.find_by_uuid(参数[:uuid])返回nil。您可以使用rails控制台通过查看生成的SQL并检查表数据来调试此问题。为什么为零?我不明白。我的本地数据库中有一些数据。请查看此查询生成的SQL。如果您仍然认为它应该为您提供数据,请在数据库客户机中执行该sql查询,并查看您得到的结果。我修复了我的规范控制器,如,描述“更新小部件分数”执行“获取小部件速率信息”执行WidgetTraffic.stub(:new)。使用({'this'=>'params'){mock_小部件_流量(:save=>true)}xhr:put,:Update,:widget\u traffic=>{'this'=>'params'}assigns(:widget\u traffic)=@mock\u widget\u traffic response.should应该是\u success end end但是我在这次看到了这些错误,1)RwsController Update widget score获取widget速率信息失败/错误:put:Update,id:@widget,widget:Factory.attributes\u for(:widget)NoMethodError:undefined method
score='for nil:NilClass#./app/controllers/rws_controller.rb:23:in
update'./spec/controllers/rws_controller_spec.rb:34:in`block(3层)in',这意味着Widget.find_by_uuid(参数[:uuid])返回nil。您可以使用rails控制台通过查看生成的SQL并检查表数据来调试此问题。为什么为零?我不明白。我的本地数据库中有一些数据。请查看此查询生成的SQL。如果您仍然认为它应该为您提供数据,请在数据库客户机中执行该sql查询,并查看得到的结果。