我有功能测试,它有两个重复的部分:
require 'spec_helper'
describe "Messages manage" do
let (:user) { create :user }
let (:other_user) { create :use }
before(:each) do
login_as user
end
describe "[message create]" do
it "messages created by self, should appear on the page", js: true do
message_text = "Hello my friend"
visit user_messages_path(user, {with:other_user.id} )
fill_in :message_body, with: message_text
click_button t("users.messages.index.send")
sleep 1 # waiting for js
page.should have_content(message_text)
find_field(:message_body).value.should == ""
page.should have_selector('#message_body', visible: false)
end
it "message errors should be displayed", js: true do
message_text = "123"
visit user_messages_path(user, {with:other_user.id} )
fill_in :message_body, with: message_text
click_button t("users.messages.index.send")
sleep 1 # waiting for js
page.should_not have_content("Message: #{message_text}")
find_field(:message_body).value.should == message_text
page.should have_selector('.message.error', visible: true)
end
end
end
在这种情况下,使用shared_examples或类似的东西的最佳方式是什么?跟随DRY。
答案 0 :(得分:3)
您可以在代码
下添加特定方法require 'spec_helper'
describe "Messages manage" do
# let (:user) { create :user }
# Instead expose it as instance variable
@user = create(:user)
# let (:other_user) { create :user }
@other_user = create(:user)
before(:each) do
login_as user
end
describe "[message create]" do
it "messages created by self, should appear on the page", js: true do
# Use the custom method
send_message "Hello my friend"
page.should have_content(message_text)
find_field(:message_body).value.should == ""
page.should have_selector('#message_body', visible: false)
end
it "message errors should be displayed", js: true do
# Use the custom method
send_message "123"
page.should_not have_content("Message: #{message_text}")
find_field(:message_body).value.should == message_text
page.should have_selector('.message.error', visible: true)
end
end
def send_message(message_text)
visit user_messages_path(@user, {with:@other_user.id} )
fill_in :message_body, with: message_text
click_button t("@users.messages.index.send")
sleep 1 # waiting for js
end
end
对于更通用的代码,您可以将它们提取到模块中的spec / support中。但对于这种情况,上述方法应该足够好了。
答案 1 :(得分:2)
我认为您没有足够的类似代码来处理shared_examples_for
块(尽管可以在 spec / support / utilities.rb 中为实用程序方法添加参数) ,所以我试图把它分开一点。
对于这个问题,很难定量给出正确的答案,因为很大程度上取决于你的编码风格,正如围绕@BillyChan的答案所讨论的那样。我的风格是尝试尽可能简洁可读;其他人可能会觉得它太干了,有些人认为不够干。不知道这是否真的有效,因为我没有你的代码,而是供你考虑......
require 'spec_helper'
describe "Message management" do
let(:user) { create :user }
let(:other_user) { create :user }
before { login_as user }
subject { page }
describe "message creation" do
let(:send_button) { t("users.messages.index.send") }
before { visit user_messages_path(user, { with: other_user.id }) }
context "by self", js: true do
let(:message_text) { "Hello my friend" }
before do
fill_in :message_body, with: message_text
click_button send_button
sleep 1 # waiting for js
end
it { should have_content(message_text) }
it { should have_selector('#message_body', visible: false) }
specify { find_field(:message_body).value.should == "" }
end
describe "message errors", js: true do
let(:message_text) { "123" }
before do
fill_in :message_body, with: message_text
click_button send_button
sleep 1 # waiting for js
end
it { should_not have_content("Message: #{message_text}") }
it { should have_selector('.message.error', visible: true) }
specify { find_field(:message_body).value.should == message_text }
end
end
end
编辑 @ole所要求的进一步说明:
specify
是it
的别名。我在这里使用specify
因为我认为这句话读得更好(你可以很容易地将其替换为it
)。此外,it
块中的条件与subject
的{{1}}相关,而page
块中的内容基本上不直接引用specify
并且正在“更改测试的page
”。如果我想将subject
块中的代码放入我认为可读的,虽然有点冗长的specify
块中,我可能会将其更改为:
it
如果您愿意,也可以删除describe "message errors", js: true do
let(:message_text) { "123" }
before do
fill_in :message_body, with: message_text
click_button send_button
sleep 1 # waiting for js
end
it { should_not have_content("Message: #{message_text}") }
it { should have_selector('.message.error', visible: true) }
describe "message body value" do
let(:message_body) { find_field(:message_body).value }
subject { message_body }
it { should == message_text }
end
end
语句并将let
直接放入find_field(:message_body).value
块。这都是品味和风格的问题。这个语法适用于此示例吗?你决定: - )