【问题标题】:rspec assigning variables - ERROR: expected: "Completed" got: "pending" (compared using ==)rspec 分配变量 - 错误:预期:“已完成”得到:“待定”(使用 == 比较)
【发布时间】:2015-04-30 19:24:57
【问题描述】:

我正在使用 RSPEC 和工厂在 ruby​​ on rails 中测试我的控制器(使用 工厂女工) 控制器代码:

class JobsController < ApplicationController
  before_action :authenticate_member!
  before_action :set_job

def complete
  @job.status = "completed"
  @job.save!
  Event.where("job_id = ? AND starts_at > ?", @job.id, DateTime.now).destroy_all
  redirect_to scheduler_path
  puts @job.inspect
end

  def set_job
    @job = Job.find(params[:id] || params[:job_id])
  end

end

RSPEC 代码:

describe JobsController do
  login_user

  before do 
    @job=FactoryGirl.create(:job)
  end

  describe "Complete Action" do 
    it "sets job status to complete" do 
      puts @job.inspect
      get :complete, :id=>@job.id
      @job.status.should eq("Completed")
    end
  end

错误:

 expected: "Completed" got: "pending" (compared using ==)

注意控制器代码的输出是:

#<Job id: 12, name: nil, status: "completed">

所以我知道它在控制器中发生了变化,但是为什么它在 factory girl 中回到“待定”?注 2:待定是默认值。 我是不是误解了控制器和工厂女孩的关系?

请帮忙?!

【问题讨论】:

    标签: ruby-on-rails testing rspec controller factory-bot


    【解决方案1】:

    这里发生了太多事情。

    首先,当状态设置为completed 和小写c 时,您不能指望Completed 带有大写C

    其次,puts @job.inspect 有两条线——一条在控制器中,一条在测试中;确保您能够区分两者的输出。

    最后,在控制器测试中,在get 语句之后,您需要一个@job.reload 来确保@job 对象已从数据库中更新。如果没有@job.reload,您仍然会看到@job.status 的原始值——它被正确设置为pending(我假设由工厂)

    请参阅https://stackoverflow.com/a/7449957/429758 以更全面地解释为什么需要@job.reload

    完整的控制器测试如下:

    describe "Complete Action" do 
      it "sets job status to complete" do 
        @job.status.should eq("pending") # Optionally check the original status
        get :complete, :id=>@job.id
        @job.reload
        @job.status.should eq("completed")
      end
    end
    

    【讨论】:

      【解决方案2】:

      您或许应该尝试重新加载@job

      @job.reload.status.should eq "completed"
      

      请注意,我已将您预期的字符串中的 Completed 更改为 completed

      旁注

      除此之外,我注意到您使用before_action 来检索作业,这可以通过不同的方式完成。您也没有检查作业是否已保存,并且始终重定向到scheduler_path。你可能想改变它。我个人会做这样的事情:

      class JobsController < ApplicationController
        before_action :authenticate_member!
      
        def complete
          if job.update_attributes status: :completed
            Event.where("job_id = ? AND starts_at > ?", job.id, DateTime.now).destroy_all
            redirect_to scheduler_path
          else
            # do something else, perhaps redirect to scheduler_path with an alert?
          end
        end
      
        def job
          @job ||= Job.find(params[:id] || params[:job_id])
        end
      
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-25
        相关资源
        最近更新 更多