我听说在RSpec中避免its, let, let!, specify, before,
和subject
是最佳做法。
关于let, let!
和before
,如果不使用这些任务,我该如何执行设置任务?
答案 0 :(得分:8)
写这些最佳实践的人实际上只想说“不要使用RSpec”。避免使用核心功能仍然是疯狂的,但仍然认为你可以很好地完成任务。你能链接到这些最佳实践吗?我喜欢阅读它们,看看它们是否合理,或者仅仅是一些j-random-guy的意见。
避免before
和let
?什么?真的?
避免使用specify
,我猜,它只是it
的旧语法。
避免特定的subject
电话?我想,如果你的代码生活在一个理想主义的幻想世界里。努力减少它并使用隐含主题?肯定。
避免its
?这很棒!为什么要避免呢?自记单行规格?多可怕啊。
答案 1 :(得分:6)
来源:有些人询问了所有这些的来源。我认为这来自thoughtbot best practices guides。
答案:在阅读该指南之后,我几乎感到非常恐惧,但在做了一些研究后,我发现了来自同一个人Let's Not的非常好解释的帖子。这是一篇非常好的阅读材料,对一般的测试和良好实践提出了很多有见地的建议。
对该指南存在一些普遍的误解。只是说“避免”而不是“不要使用”。结果代码将更清晰,更易于维护。 我将引用帖子反映的一些观点:
这对我来说很有意义。 希望这会有所帮助。
答案 2 :(得分:1)
如果您真的想研究rspec的最佳实践,我使用的一些资源是:
答案 3 :(得分:1)
答案 4 :(得分:1)
我听说这是最佳做法
如果你能引用一些来源会很有帮助。我相信你听到的陈述非常不准确。
避免
its
我个人不使用its
,但这是一个偏好问题。自its
is a short-hand method起,您通常可以使用扩展版本。
避免
let
,let!
没有理由避免它们。 official documentation并没有阻止他们,事实上他们正在积极宣传。
从技术上讲,您可以通过定义方法来替换它们。
let(:foo) { 1 }
与
“等效”def foo
@foo ||= 1
end
但正如您所看到的,使用let
更方便有效。
避免
specify
specify
是it
的别名。
避免
before
这没有意义。如果需要,无法避免before
,官方文档也不会弃用它。
避免
subject
绝对错误。文档鼓励使用它。
底线。我坚信你听到的是假的。请查看the documentation以了解如何有效使用RSpec。
答案 5 :(得分:1)
因为这里没有答案是针对实际问题,而是针对所提及的做法发表意见,所以我觉得有必要再添加一个答案,即使距被问起已有7年6年了。
所有“有问题的” DSL方法都可以替换为普通的旧Ruby方法。您仍然可以保持DRY状态,而不必使用会使代码的不同部分转移注意力的方法。
以下代码直接从Noel Rappin的Rails 5 Test Prescriptions一书中提取
describe "estimates" do
let(:project) { Project.new }
let(:done) { Task.new(size: 2, completed: true) }
let(:small_not_done) { Task.new(size: 1) }
let(:large_not_done) { Task.new(size: 4) }
before(:example) do
project.tasks = [done, small_not_done, large_not_done]
end
it "can calculate total size" do
expect(project.total_size).to eq(7)
end
it "can calculate remaining size" do
expect(project.remaining_size).to eq(5)
end
end
用普通的Ruby方法代替
describe "estimates" do
it "can calculate total size" do
project = build_new_project
project.tasks = build_done_small_and_large_tasks
expect(project.total_size).to eq(7)
end
it "can calculate remaining size" do
project = build_new_project
project.tasks = build_done_small_and_large_tasks
expect(project.remaining_size).to eq(5)
end
def build_new_project
Project.new
end
def build_new_task(size=1, completed=false)
Task.new(size: size, completed: completed)
end
def build_done_small_and_large_tasks
tasks = []
tasks << build_task(2, true)
tasks << build_task(1, false)
tasks << build_task(4, false)
tasks
end
end
依我和Thoughtbot的观点,这种方法有很多优点:
另一方面,重点是要在每个测试中尽可能明确地显示每个测试阶段
示例:
it "can calculate total size" do
# Setup
project = build_new_project
project.tasks = build_done_small_and_large_tasks
# Exercise and verification
# Exercise is the "total_size" method, because that is what we are testing
# Verification is the expectations of what should happen after the exercise
expect(project.total_size).to eq(7)
end
# Teardown is performed by Rspec, you may also perform it yourself in after blocks
最后,一个公司的风格指南永远无法满足所有目的或其他公司的需求。据我所知,这种方法对于测试驱动的开发特别有用,在该开发中,代码必须由每个失败的测试所建议的修复测试的驱动。因此,说您不应遵循这种方法是很主观的。它有很好的论据,也有一些缺点,一如既往,您应该权衡它们,并坚持最适合自己的方法。就我而言,我发现这些测试更易于阅读,对于理解应用程序的每个模块更有用,而不是简单地在出现问题时通知您,我喜欢编写可记录自身的代码。这种方法将使您清楚地看到将来的代码将如何使用以及每种情况的预期结果。 RSpec不只是DSL方法。
有关TDD的更多信息以及如何遵循这种测试方法,请查看如何Tell a Story With Your Tests