RSpec中Post分类复选框匹配器缺失的解决方案咨询
解决RSpec中测试分类复选框存在/不存在的问题
首先得说,你遇到的have_checkbox匹配器不存在的问题很常见——Capybara本身并没有提供这个专属匹配器,我们需要用通用的have_field匹配器来定位复选框,因为复选框本质是type="checkbox"的input字段。
基础写法:检测复选框是否存在/不存在
针对你的场景,要测试"Sports"分类的复选框不存在,正确的写法应该是:
expect(page).not_to have_field("Sports", type: "checkbox")
反过来,如果要验证有权限的用户能看到这个复选框,就用:
expect(page).to have_field("Sports", type: "checkbox")
注意:匹配实际的HTML元素
有时候用f.association :categories, as: :check_boxes生成的复选框,其label文本可能和你想的不完全一致(比如如果你的分类名称是动态生成的,或者关联字段有命名空间)。这时候可以先查看页面的HTML结构,确认复选框的label文本、id或者name属性,再调整匹配方式:
- 如果知道分类的ID,也可以通过value匹配:
expect(page).not_to have_field(nil, type: "checkbox", value: sports_category.id.to_s) - 或者通过label的for属性关联的input id来定位:
expect(page).not_to have_field("post_category_ids_#{sports_category.id}", type: "checkbox")
结合Pundit权限的场景测试
因为你用policy(post).change_category?来控制复选框的显示,建议分两种场景写测试:
- 有权限的用户:登录拥有
change_category?权限的用户,访问表单页面,验证分类复选框组(包括"Sports")是否存在context "when user has permission to change categories" do let(:user) { create(:user, :can_change_categories) } before { sign_in user } it "displays the category checkboxes" do visit edit_post_path(post) expect(page).to have_field("Select the Categories:") # 验证分组标签存在 expect(page).to have_field("Sports", type: "checkbox") end end - 无权限的用户:登录没有该权限的用户,验证整个分类复选框区域都不显示
context "when user does NOT have permission to change categories" do let(:user) { create(:user) } before { sign_in user } it "does NOT display the category checkboxes" do visit edit_post_path(post) expect(page).not_to have_text("Select the Categories:") expect(page).not_to have_field("Sports", type: "checkbox") end end
额外:测试复选框是否被选中
如果需要验证某个分类复选框默认是选中状态,还可以加上checked: true参数:
expect(page).to have_field("Sports", type: "checkbox", checked: true)
内容的提问来源于stack exchange,提问作者rld
相关产品推荐
相关产品推荐

