我正在对象上创建一个解析方法,所以我可以这样做:
@address = Address.parse("123 Main St, San Francisco CA")
我想构建一个潜在用户输入库(“支持的格式”等),我可以使用它来确保复杂的正则表达式更改在一个地方不会破坏其他人。
我想为这个功能创建大量的单元测试(应该称之为集成测试),我想用它来固定:
fixtures/address_inputs.rb
one:
address: 123 Main St, San Francisco CA
two:
address: 234 Center Road San Francisco, CA
然后我可以循环遍历所有灯具以验证对象中的结果数据:
@addresses.each do |address|
assert_true address.street_number.to_i > 0
end
或类似的东西。
但是,我无法使用fixtres,因为数据与ActiveRecord表无关。 我收到很多这样的错误:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table
如何创建测试夹具以对任意输入进行单元测试?我应该使用不同的工具来处理这些集成测试吗?
答案 0 :(得分:1)
@address = Address.parse("123 Main St, San Francisco CA")
assert_equal @address.street_number, "123"
但是如果您使用了'fixture'(或者存储在外部文件中的某些数据),那么稍后您将更难以阅读测试,并且以后的其他开发人员将会更难以阅读(请注意,我不使用灯具,我更喜欢factory_girl,所以我提出了语法。这可能是错的,但重点是:)
@address = Address.parse(fixture(:address_one))
assert_equal @address.street_number, "123"
你为什么断言street_number是“123”?如果在以后的问题出现问题,很难看出测试是否写得正确。你必须转到外部文件,这只是一个非常大的痛苦。
我确实发现外部灯具(再次,我使用factory_girl)对于设置像这样的对象的某些状态很有用:
Factory.define :user do |f|
f.sequence(:email){ |n| "testemail#{n}@example.net" }
f.first_name "Test"
f.last_name "User"
end
Factory.define :admin_user, :parent => :user do |f|
f.admin true
end
这样我就可以在需要的时候为测试创建一个admin_user,如果用户管理员更改的定义更容易让所有依赖它的测试更正确。但是,这不是为了测试@ user.admin属性的特定行为,而是更像是“用户可以访问此操作吗?”等权限。
如果我稍后使用:user工厂并想测试'email'属性的特定行为,我将不依赖于工厂提供的内容。我会像这样创建对象:,覆盖默认的电子邮件字段:
@user = Factory.create(:user, :email => "myemail@example.net")
使测试更清晰。
我认为你的例子是不合适的,你依靠夹具中的文本字符串来确定你的断言是什么样的。