如何通过其他模型创建集成测试

1)我有这个模型Job和模型机构

class Job < ApplicationRecord belongs_to :institution # others attibutes end 

2)这是我在JobsController上创建的动作 – 我需要一个机构来创建一份工作。 没事。

 def create build_job save_job || render(:new, status: :unprocessable_entity) end 

3)这是我创建的集成测试我没有得到成功测试

params -I also tried institution: @institution -and also tried institution_id: @institution.id

 require 'test_helper' class JobActionsTest < ActionDispatch::IntegrationTest setup do @user = users(:standard) sign_in @user @institution = institutions(:standard) end test "can create a job through institution" do get new_institution_job_path(@institution) assert_response :success assert_difference('Job.count') do post jobs_path, params: {job: {title: "Desenvolvedor", description: "Ruby", requirements: "rspec and capybara", start_date: Date.today, end_date: Date.today + 5.days, institution: @institution.id}} end assert_response :redirect follow_redirect! assert_response :success end end 

4)这是我的控制台错误

 #Running: E Error: JobActionsTest#test_can_create_a_job_through_institution: ActiveRecord::RecordNotFound: Couldn't find Institution with 'id'= app/controllers/jobs_controller.rb:74:in `job_scope' app/controllers/jobs_controller.rb:52:in `build_job' app/controllers/jobs_controller.rb:18:in `create' test/integration/job_actions_test.rb:22:in `block (2 levels) in ' test/integration/job_actions_test.rb:21:in `block in ' bin/rails test test/integration/job_actions_test.rb:17 

首先正确嵌套jobs资源:

 resources :institutions do resources :jobs, only: [:new, :create] end # or to create the full suite resources :institutions do resources :jobs, shallow: true end 

这将给出这些路线:

  Prefix Verb URI Pattern Controller#Action institution_jobs POST /institutions/:institution_id/jobs(.:format) jobs#create new_institution_job GET /institutions/:institution_id/jobs/new(.:format) jobs#new ... 

请注意:institution_id现在是创建路径的URI模式的一部分,它将以params[:institution_id]

在您的测试中,您希望POST到/institutions/:institution_id/jobs

 require 'test_helper' class JobActionsTest < ActionDispatch::IntegrationTest setup do @user = users(:standard) sign_in @user @institution = institutions(:standard) end # Use separate examples per route / case test "can fill in form to create a new job" do get new_institution_job_path(@institution) assert_response :success end test "can create a job through institution" do assert_difference ->{ @institution.jobs.count } do post institution_jobs_path(@institution), params: { job: { title: "Desenvolvedor", description: "Ruby", requirements: "rspec and capybara", start_date: Date.today, end_date: Date.today + 5.days } } end assert_redirected_to @institution.jobs.last follow_redirect! assert_response :success end end 

此外,您想测试实际上是为正确的机构创建的作业。 我们通过传递lambda ->{ @institution.jobs.count }做到这一点。

并且用户被重定向到正确的资源 – 而不仅仅是某个地方 – 这是通过assert_redirected_to @institution.jobs.last来完成的。

当你在第22行打电话时,它看起来像是

 get new_institution_job_path(@institution) 

您在setup块中构建的@institution对象未保存在数据库中。

您收到的错误ActiveRecord::RecordNotFound表示无法找到ID为nil的机构。

您可以通过添加此断言轻松检查我是否正确猜测:

  test "can create a job through institution" do assert_not_nil(@institution.id) # or assert_not_equal(0, Institution.where(id: @institution.id).size) get new_institution_job_path(@institution) assert_response :success #... end 

确保您的institutions(:standard)方法看起来像Institution.create!()而不是像Institution.newInstitution.build