因为 before 块正在调用visit user_path(user)
用户值在那里初始化,RSpec 将访问该页面。如果:m1
:m2
没有使用let!
那么访问不会产生任何内容
it { should have_content(m1.content) }
it { should have_content(m2.content) }
失败,因为它期望在用户访问该页面之前创建微帖子。let!
允许在调用 before 块之前创建微帖子,并且当测试访问该页面时,微帖子应该已经创建。
编写相同测试并让它们通过的另一种方法是执行以下操作:
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
let(:m1) { FactoryGirl.create(:micropost, user: user, content: "Foo") }
let(:m2) { FactoryGirl.create(:micropost, user: user, content: "Bar") }
before do
m1
m2
visit user_path(user)
end
调用变量m1
and m2
before visit user_path(user)
导致它们在访问页面之前被初始化并导致测试通过。
UPDATE这个小例子会更有意义:
在此示例中,我们调用 get_all_posts ,它仅返回帖子数组。请注意,我们在断言之前和之前调用该方法it
块被执行。因为在执行断言之前不会调用 post 。
def get_all_posts
Post.all
end
let(:post) { create(:post) }
before { @response = get_all_posts }
it 'gets all posts' do
@response.should include(post)
end
通过使用let!
一旦 RSpec 看到该方法(在before
块)并且该帖子将返回到列表中Post
同样,另一种方法是在调用该方法之前在 before 块中调用变量名称
before do
post
@response = get_all_posts
end
因为这将确保let(:post)
在调用方法本身之前调用块创建Post
以便它返回Post.all
call