重构 Rspec 规范
我正在尝试清理我的规格,因为它们变得极其重复。
我有以下规范
describe "Countries API" do
it "should render a country list" do
co1 = Factory(:country)
co2 = Factory(:country)
result = invoke :GetCountryList, "empty_auth"
result.should be_an_instance_of(Api::GetCountryListReply)
result.status.should be_an_instance_of(Api::SoapStatus)
result.status.code.should eql 0
result.status.errors.should be_an_instance_of Array
result.status.errors.length.should eql 0
result.country_list.should be_an_instance_of Array
result.country_list.first.should be_an_instance_of(Api::Country)
result.country_list.should have(2).items
end
it_should_behave_like "All Web Services"
it "should render a non-zero status for an invalid request"
end
检查状态的代码块将出现在我的 50-60 个 API 的所有规范中。我的第一个想法是将其转移到一种方法中,而重构肯定会使事情变得更加干燥,如下所示:-
def status_should_be_valid(status)
status.should be_an_instance_of(Api::SoapStatus)
status.code.should eql 0
status.errors.should be_an_instance_of Array
status.errors.length.should eql 0
end
describe "Countries API" do
it "should render a country list" do
co1 = Factory(:country)
co2 = Factory(:country)
result = invoke :GetCountryList, "empty_auth"
result.should be_an_instance_of(Api::GetCountryListReply)
status_should_be_valid(result.status)
result.country_list.should be_an_instance_of Array
result.country_list.first.should be_an_instance_of(Api::Country)
result.country_list.should have(2).items
end
end
这可行,但是我不禁觉得这不是“正确”的方法,我应该使用共享规范,但是,查看定义共享规范的方法,我无法轻松了解如何重构此示例以使用共享规范。
我如何使用共享规格来做到这一点,而不必在开始时重新运行相对昂贵的块
co1 = Factory(:country)
co2 = Factory(:country)
result = invoke :GetCountryList, "empty_auth"
I am trying to cleanup my specs as they are becoming extremely repetitive.
I have the following spec
describe "Countries API" do
it "should render a country list" do
co1 = Factory(:country)
co2 = Factory(:country)
result = invoke :GetCountryList, "empty_auth"
result.should be_an_instance_of(Api::GetCountryListReply)
result.status.should be_an_instance_of(Api::SoapStatus)
result.status.code.should eql 0
result.status.errors.should be_an_instance_of Array
result.status.errors.length.should eql 0
result.country_list.should be_an_instance_of Array
result.country_list.first.should be_an_instance_of(Api::Country)
result.country_list.should have(2).items
end
it_should_behave_like "All Web Services"
it "should render a non-zero status for an invalid request"
end
The block of code that checks the status will appear in all of my specs for 50-60 APIs. My first thought was to move that to a method and that refactoring certainly makes things much drier as follows :-
def status_should_be_valid(status)
status.should be_an_instance_of(Api::SoapStatus)
status.code.should eql 0
status.errors.should be_an_instance_of Array
status.errors.length.should eql 0
end
describe "Countries API" do
it "should render a country list" do
co1 = Factory(:country)
co2 = Factory(:country)
result = invoke :GetCountryList, "empty_auth"
result.should be_an_instance_of(Api::GetCountryListReply)
status_should_be_valid(result.status)
result.country_list.should be_an_instance_of Array
result.country_list.first.should be_an_instance_of(Api::Country)
result.country_list.should have(2).items
end
end
This works however I can not help feeling that this is not the "right" way to do it and I should be using shared specs, however looking at the method for defining shared specs I can not easily see how I would refactor this example to use a shared spec.
How would I do this with shared specs and without having to re-run the relatively costly block at the beginning namely
co1 = Factory(:country)
co2 = Factory(:country)
result = invoke :GetCountryList, "empty_auth"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一种选择,使用 RSpec 的新“主题”功能。请注意,这将运行
before :all
块两次,每个嵌套的“describe”块运行一次。如果这最终太慢,您可以将事情压平,但代价是无法对状态共享示例使用“主题”语法(因为主题适用于它所使用的整个描述块)。Here's one option, using the new-ish "subject" feature of RSpec. Note that this will run the
before :all
block twice, once for each nested "describe" block. If this ends up being too slow, you can flatten things out at the cost of not being able to use the "subject" syntax for the status shared examples (since subject applies to the entire describe block it's used in).