我听说这是避免its, let, let!, specify, before,
和subject
在 RSpec 中的最佳实践。
关于let, let!
和before
,如果不使用这些,我该如何执行设置任务?
编写这些最佳实践的人实际上只想说“不要使用 RSpec”。避免使用核心功能并仍然认为你可以把事情做好是很疯狂的。你能链接到这些最佳实践吗?我很想阅读它们,看看它们是否合理,或者只是一些 j-random-guy 的意见。
避免before
和let
?什么?真的吗?
避免specify
,我猜,这只是it
.
避免特定subject
呼叫?我想,如果你的代码生活在一个理想主义的幻想世界里。努力将其最小化并使用隐式主题?当然。
避免its
?这很棒!为什么要避免呢?自我记录的单行规范?多么可怕。
来源:有些人询问所有这些的来源。我认为这来自thoughtbot 最佳实践指南。
答案:阅读该指南后,我也几乎吓坏了,但在做了一些研究之后,我发现了来自同一个人的这篇解释得很好的帖子Let's Not。是一本非常好的读物,其中包含很多关于测试和一般良好实践的有见地的建议。
对该指南存在一些普遍的误解。只是说“避免”而不是“不要使用”。结果代码将更清晰,更易于维护。我将引用帖子反映的一些观点:
这对我来说很有意义。希望这可以帮助。
因为这里的答案都没有解决实际问题,而是给出了他们对提到的做法的意见,所以我觉得有必要添加另一个答案,即使它被问到已经 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 以及如何遵循这种测试方法的更多信息,请查看如何用测试讲述故事
我听说这是最佳实践
如果您可以引用一些来源,那将会很有帮助。我相信你听到的陈述是非常不准确的。
避免
its
我个人不使用its
,但这是一个偏好问题。由于its
是一种速记方法,因此您可以正常使用扩展版本。
避免
let
,let!
没有理由避免它们。官方文档并没有阻止他们,事实上他们正在积极宣传。
从技术上讲,您可以通过定义方法来替换它们。
let(:foo) { 1 }
是“等价于”
def foo
@foo ||= 1
end
但如您所见,使用let
起来更方便有效。
避免
specify
specify
是 的别名it
。
避免
before
这没有意义。before
如果需要,没有办法避免,官方文档也没有弃用它。
避免
subject
绝对错误。该文档鼓励使用它。
底线。我坚信你所听到的都是假的。查看文档以了解如何有效地使用 RSpec。