class Manager < ActiveRecord::Base
belongs_to :player
belongs_to :season
belongs_to :team
before_validation :validate_relations
validates :player_id, presence: true
validates :season_id, presence: true
validates :team_id, presence: true
private
def validate_relations
player = Player.find(self.player_id)
season = Season.find(self.season_id)
team = Team.find(self.team_id)
manager = Manager.find_by(player: player, season: season, team: team)
if !manager.nil? && self.id != manager.id
errors[:manager] << 'already exists.'
false
end
end
end
class ManagersController < ApplicationController
before_action :get_manager, only: [:destroy, :show, :update]
rescue_from ActionController::ParameterMissing, with: :malformed_request
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
def create
@manager = Manager.create(manager_params)
status = @manager.valid? ? :no_content : :unprocessable_entity
render_manager status
end
...
private
def manager_params
params.require(:manager).permit(:player_id, :season_id, :team_id, :league_id)
end
def malformed_request
render_manager :unprocessable_entity, 'Error message'
end
def record_not_found
render_manager :not_found, 'Error message'
end
def get_manager
@manager = Manager.includes(:player, :season, :team).find(params[:id])
end
def render_manager(status, message = nil)
...
end
def render_managers(status, managers)
...
end
end
如您所见,我的managers_controller
从ActiveRecord::RecordNotFound
获救并在客户端尝试创建无效的关联ID时相应地处理相应的响应。当明确给出请求和响应时,这很有效,但是当我rake test
时,使用无效的关联id(例如,当所有id都是nil
时)的测试总是以3个错误结束,表明rails无法找到具有给定ID的每个Model,如下所示。
1) Error:
ManagerTest#test_: Manager should require player_id to be set. :
ActiveRecord::RecordNotFound: Couldn't find Player with 'id'=
app/models/manager.rb:35:in `validate_relations'
2) Error:
ManagerTest#test_: Manager should require season_id to be set. :
ActiveRecord::RecordNotFound: Couldn't find Player with 'id'=
app/models/manager.rb:35:in `validate_relations'
3) Error:
ManagerTest#test_: Manager should require team_id to be set. :
ActiveRecord::RecordNotFound: Couldn't find Player with 'id'=
app/models/manager.rb:35:in `validate_relations'
如何重新设计测试,模型验证或错误处理以避免这些错误?
答案 0 :(得分:1)
您的Manager
模型似乎需要验证,以根据Team
,Season
和Player
模型检查当前模型是否唯一。有一个内置的验证器,称为uniqueness
(detailed docs),您只需要:
class Manager < ActiveRecord::Base
belongs_to :player
belongs_to :season
belongs_to :team
validates :player_id, uniqueness: { scope: [:team_id, :season_id] }
end
您也可以使用shoulda-matchers进行测试。
答案 1 :(得分:0)
通常,对于单元测试,您希望测试一个独立于另一个类的类,因此在您的情况下,您希望独立于模型测试控制器,因此您应该提供模型的“模拟”。
我不确定您使用的测试框架,但这里是rspec文档中的example:
您使用FactoryGirl创建样本模型数据。
答案 2 :(得分:0)
除了测试方法之外,我觉得很奇怪,验证会抛出一个not_found ......为什么不在你的验证中拯救(或使用Player.find_by(:id => self.player_id)
,这将返回nil
) ,所以你可以返回如下信息:
{
:errors => [
{ "Player" => "not found" },
{ "Season" => "not valid" },
{ "Team" => "not whatever" }
]
}