【发布时间】:2021-05-02 03:07:47
【问题描述】:
我正在为这样的方法编写测试:
def get_team_members(project_id)
team_members = []
Result.where(project_id: project_id).each do |result|
user = User.find_by(id: result.user_id)
team_members.push(user) unless user.nil?
end
team_members
end
当我在测试只找到 1 条 result 记录的情况下,我可以这样做
allow(Result).to receive(:where).with(project_id:project_id).and_return([result1])
allow(User).to receive(:find_by).with(id: valid_result[:user_id]).and_return(nil)
或
allow(Result).to receive(:where).with(project_id:project_id).and_return([result1])
allow(User).to receive(:find_by).with(id: valid_result[:user_id]).and_return(user1)
问题1:如果我想在找到2条result记录时测试案例
allow(Result).to receive(:where).with(project_id:project_id).and_return([result1, result2])
对于result1,找到匹配的user (user1),对于result2,未找到匹配的user (nil)。
在这种情况下,预期的返回值应该是team_members = [user1]。
如何使用不同的返回值 (user1, nil) 模拟两次 User.find_by()?
问题2:我真的需要测试我上面提到的案例吗?
【问题讨论】:
-
这与您提出的测试问题无关,但您的查询效率非常低 - 您将其构建为 N+1 查询 - 也就是说,对于包含 N 个团队成员的结果,您将访问数据库一次(对于您的
where语句),然后每个团队成员一次。这感觉就像你应该能够利用 Rails 的内置has_many :through选项:如果一个Projecthas_many :results,并且每个Result属于一个:user,然后声明一个项目 @ 987654341@ 意味着project.users会给你你想要的收藏。 -
是的,斯科特你是对的。数据库设计不是很好。它是由以前的团队成员构建的,我正在开发它。我可能需要稍后更新架构。
标签: ruby-on-rails unit-testing rspec mocking iteration