我正试图重构一些RSpec/Rails测试,使它们尽可能少地坚持数据库对象,但我有困难试图找出如何重写测试,如以下:
describe User do
context "record creation" do
before(:each) { @user = User.new(user_atts) }
it "should generate a confirmation_token" do
# Generated as the result of a callback
@user.save!
expect(@user.confirmation_token).to be_present
end
it "should set the confirmed_at attribute to nil" do
# Cleared as the result of a callback
@user.save!
expect(@user.confirmed_at).to be_nil
end
it "should call the send_confirmation_instructions method" do
@user.should_receive(:send_confirmation_instructions) {}
@user.save!
end
end
def user_atts
# return attributes hash
end
end
这是一个非常简单的例子,但在我的规范中有很多类似的实例,并且在大多数情况下,它们都将记录持久化到数据库中。我很想利用RSpec的let
和subject
帮助器,但我不完全确定它们在这里是否有帮助。
我一直在使用FactoryGirl很多,并认为也许它的build_stubbed
策略会加快我的规格一点,但我找不到很多实例,它会帮助限制实际的记录创建(或者也许我不知道如何使用)。
我的测试可能看起来像这样。
describe User do
let(:user) { FactoryGirl.build_stubbed(:user) }
context "record creation" do
it "should generate a confirmation_token" do
user.save!
expect(user.confirmation_token).to be_present
end
it "should set the confirmed_at attribute to nil" do
user.save!
expect(user.confirmed_at).to be_nil
end
it "should call the send_confirmation_instructions method" do
expect(user).to receive(:send_confirmation_instructions).once
user.save!
end
end
end
就是使用Factory Girl来创建用户模型。此外,我将有DatabaseCleaner在每次测试后清除数据库,如@RahulGarg
所述。你所要做的就是在spec_helper中这样配置
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
这意味着在每次测试之后,数据库将被清除。