【问题标题】:How to do Integration Test create through other model如何通过其他模型创建集成测试
【发布时间】:2017-09-27 12:49:31
【问题描述】:

1) 我有这个模范职位和模范机构

class Job < ApplicationRecord
  belongs_to :institution
  # others attibutes
end

2) 这是我在 JobsController 上创建的操作 - 我需要一个机构来创建工作。没关系。

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

3) 这是我创建的集成测试 我没有通过成功测试

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


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

【问题讨论】:

    标签: ruby-on-rails ruby integration-testing


    【解决方案1】:

    从正确嵌套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 -&gt;{ @institution.jobs.count } 来做到这一点。

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

    【讨论】:

    • 非常感谢。这对我有用。您关于如何走正确路线以及如何为合适的机构创造工作的提示帮助我理解了。
    【解决方案2】:

    在第 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

    【讨论】:

    • 你确定吗? institutions(:standard) 看起来他正在访问 a fixture。它们是在每次测试运行之前在数据库中创建的。
    • 我不能 100% 确定,因为我的测试套件通常是 rspec,而我使用 factory_girl 作为固定装置。但是,OP 收到的错误消息是 RecordNotFound,所以我假设在测试期间他找不到带有 nil id 的记录(根据回溯)。我同意 @institution 是一个 ActiveRecord 实例,但我猜它没有保存在数据库中。也许值得在设置块中尝试@institution.save!
    • 实际上get new_institution_job_path(@institution); assert_response :success 行正在传递,这应该意味着记录是持久的。但这很难说,因为每个人都像疯子一样在 minitest 中编写集成测试。
    猜你喜欢
    • 2020-03-30
    • 2019-08-27
    • 1970-01-01
    • 2021-01-03
    • 2023-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多