如何为返回集合的select_collection函数编写测试用例?
测试实现方案
方式一:Mock数据库查询返回模拟对象
如果不想依赖真实数据库,直接mock OrganizationalUnit.where 的返回值,对比模拟集合与函数结果:
# 你的spec文件代码 let(:section) { create(:section) } # 假设使用FactoryBot创建section实例 let(:type) { create(:type) } let(:scenaries) { [ double(:organizational_unit, section_id: section.id, type_id: type.id), double(:organizational_unit, section_id: section.id, type_id: type.id) ] } it "returns the expected simulated collection" do # 让OrganizationalUnit.where返回预设的模拟集合 allow(OrganizationalUnit).to receive(:where).with('section.id = ? ...', any_args).and_return(scenaries) # 断言函数返回结果与模拟集合一致 expect(select_collection).to eq(scenaries) end
注意:如果明确知道
where的完整参数,把any_args换成具体参数(比如with('section.id = ?', section.id)),测试会更严谨。
方式二:用真实数据库记录测试(推荐)
要验证查询逻辑的正确性,建议用真实数据库记录测试,避免mock导致的假阳性:
# 你的spec文件代码 let(:section) { create(:section) } let(:type) { create(:type) } # 创建2条符合查询条件的真实OrganizationalUnit记录 let(:expected_units) { create_list(:organizational_unit, 2, section_id: section.id, type_id: type.id) } it "returns the correct collection of OrganizationalUnit records" do # 创建1条不符合条件的记录,验证查询不会返回它 create(:organizational_unit, section_id: create(:section).id, type_id: type.id) result = select_collection # 用match_array忽略顺序,只验证元素一致 expect(result).to match_array(expected_units) # 验证结果数量符合预期 expect(result.count).to eq(2) end
关键提示
- 如果
select_collection是实例方法,要确保调用正确的实例(比如subject.select_collection)。 - 使用
match_array而非eq,因为数据库查询返回的集合顺序可能和创建顺序不一致。
内容的提问来源于stack exchange,提问作者mtsyumm
相关产品推荐
相关产品推荐

