How to do Integration Test create through other mo

2019-08-23 03:53发布

1) I have this model Job and the model institution

class Job < ApplicationRecord
  belongs_to :institution
  # others attibutes
end

2) This is my action create on JobsController - I need a institution to create a job. it is fine.

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

3) This is the integration test that I created I am not getting the success test

In 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) And this is my console error

#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 <class:JobActionsTest>'
    test/integration/job_actions_test.rb:21:in `block in <class:JobActionsTest>'


bin/rails test test/integration/job_actions_test.rb:17

2条回答
淡お忘
2楼-- · 2019-08-23 04:27

It looks like that when you call at line 22

get new_institution_job_path(@institution)

the @institution object you have built in the setup block is not saved in the database.

The error you are receiving, ActiveRecord::RecordNotFound, says that it cannot be found an Institution with id nil.

You can easily check if I am guessing correctly by adding this assertion:

  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

Make sure that your institutions(:standard) method looks like Institution.create!() and not like Institution.new or Institution.build

查看更多
倾城 Initia
3楼-- · 2019-08-23 04:47

Start by nesting the jobs resource properly:

resources :institutions do
  resources :jobs, only: [:new, :create]
end

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

This will give these routes:

             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
...

Note that :institution_id is a now a part of URI pattern for the create route, and it will be available as params[:institution_id].

In your test you want to POST to /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

Further you want to test that the job actually was created for the right institution. We do that by passing the lambda ->{ @institution.jobs.count }.

And that the users are redirected to the correct resource - not just somewhere - which is done with assert_redirected_to @institution.jobs.last.

查看更多
登录 后发表回答