如何通过其他模型进行集成测试创建
How to do Integration Test create through other model
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
当你在第 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.new
或 Institution.build
首先正确嵌套 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
完成的。
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
当你在第 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.new
或 Institution.build
首先正确嵌套 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
完成的。