On Mon, Aug 6, 2012 at 6:06 PM, Karl <[email protected]> wrote:
> On Monday, August 6, 2012 2:51:49 PM UTC-7, [email protected] wrote:
>>
>> On Mon, Aug 6, 2012 at 5:16 PM, Karl  wrote:
>> > I would appreciate some help refactoring this shared_example.
>> >
>> > describe "Sending Notifications" do
>> >   before(:all) do
>> >     create_basic_company_area_store # sets @company, @area, @store
>> >     @user = FactoryGirl.create(:user)
>> >     @company2 = FactoryGirl.create(:company)
>> >   end
>> >
>> >   shared_examples "sends all types" do
>> >     it 'sends an email' do
>> >       FactoryGirl.create(:email_notification, notification_type:
>> > notif_type,
>> > user: user)
>> >       notification_email_with_expects(resource, expected_str)
>> >     end
>> >   end
>> >
>> >   describe 'Something Bad Happens' do
>> >     it_behaves_like "sends all types" do
>> >       let(:notif_type) { NotificationType.find_by_name("bad stuff") }
>> >       let(:user) { @user }
>> >       let(:resource) { @company2 }
>> >       let(:expected_str) { @company2.name }
>> >     end
>> >   end
>> >
>> >   describe 'Something Even Worse Happens' do
>> >     it_behaves_like "sends all types" do
>> >       let(:notif_type) { NotificationType.find_by_name("really bad
>> > stuff") }
>> >       let(:user) { @user }
>> >       let(:resource) { @company2 }
>> >       let(:expected_str) { @company2.name }
>> >     end
>> >   end
>> >
>> > end
>> >
>> > It works. But as I will need to test about 100 notification types, all
>> > those
>> > 'let' statements will be a bit repetitious. How can I write this and
>> > maybe
>> > knock it down to just 'it_behaves_like' single lines.
>>
>> What actually needs to be different in each example? It seems like
>> you're using the same @user each time, so that could be expressed in
>> the shared example e.g.
>>
>> shared_examples "sends all types" do
>>   it 'sends an email' do
>>     FactoryGirl.create(:email_notification,
>>       notification_type: notif_type, user: FactoryGirl.create(:user))
>>     notification_email_with_expects(resource, expected_str)
>>   end
>> end
>>
>> You can also move the notification type to the shared example - just
>> passing in the name used to look up the type:
>>
>> shared_examples "sends all types" do |notification_type_name|
>>   it 'sends an email' do
>>     FactoryGirl.create(:email_notification,
>>       notification_type:
>> NotificationType.find_by_name(notification_type_name),
>>       user: FactoryGirl.create(:user))
>>     notification_email_with_expects(resource, expected_str)
>>   end
>> end
>>
>> describe 'Something Bad Happens' do
>>   it_behaves_like "sends all types", "bad stuff" do
>>     let(:resource) { @company2 }
>>     let(:expected_str) { @company2.name }
>>   end
>> end
>>
>> Then it seems like @company2 can be declared within the example as well:
>>
>>
>> shared_examples "sends all types" do |notification_type_name|
>>   it 'sends an email' do
>>     company = FactoryGirl.create(:company)
>>     FactoryGirl.create(:email_notification,
>>       notification_type:
>> NotificationType.find_by_name(notification_type_name),
>>       user: FactoryGirl.create(:user))
>>     notification_email_with_expects(company, company.name)
>>   end
>> end
>>
>> describe 'Something Bad Happens' do
>>   it_behaves_like "sends all types", "bad stuff"
>> end
>>
>> I'm sure I'm missing some things, but you get the idea.
>>
>> Cheers,
>> David
> David,
> I should have been more clear...
>
> 1. The spec will be for each NotificationType. Somewhere south of 100, for
> now. Something like
>
>   it_behaves_like "send all types", "bad stuff"
>   it_behaves_like "send all types", "really bad stuff"
>   ... x 80 or so...
>
> 2. I agree with your reply. I could move the @company2, @user into the
> shared example, but then it will create those records for every test, and I
> want to avoid that. In this particular case, it's just not necessary and
> slows the spec.
>
> So, I really don't want to create those @company2 and @user records in every
> test. As you know, they will not exist out side the scope of the test, so I
> can't do:
>
>  it_behaves_like "send all types", "bad stuff", @company, @user, ...
>
> Ok, they don't instantiate until after the first spec is executed because
> they are in a before(:all). Is there a way to force them into existence,
> just once?

Nothing built in. rspec-rails defers to Rails' transaction management,
which is designed to clean up after every example. You'd have to
disable that and roll your own using a tool like database cleaner.

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to