Hello, Previously I''ve had a helper assert_no_database like this: def assert_no_database old_con = ActiveRecord::Base.remove_connection begin yield ensure ActiveRecord::Base.establish_connection old_con end end But it doesn''t work in Rails 3.1.1 anymore (due to the following change: https://github.com/rails/rails/issues/2820) Any suggestion for a proper way to check that a block of code doesn''t access database? Thanks, KIR -- Kirill (KIR) Maximov Software Engineer & Starter Twitter: http://twitter.com/maxkir Skype: maxkir http://kirblog.idetalk.com | http://checkvist.com | http://www.jetbrains.com/teamcity -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Mislav Marohnić
2011-Oct-15 22:01 UTC
Re: A proper way to test that database is not accessed?
On Oct 15, 2011, at 10:19 PM, KIR wrote:> Any suggestion for a proper way to check that a block of code doesn''t access database?How about: ActiveRecord::Base.establish_connection Rails.env -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
> > ActiveRecord::Base.establish_connection Rails.env >I don''t quite understand what do you mean here? My problem is that code like the following results in ConnectionNotEstablished exception (though it worked in 3.1): model = Task.first old_con = ActiveRecord::Base.remove_connection model.any_attr_name # check no access to DB ActiveRecord::Base.establish_connection old_con> > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > >-- Kirill (KIR) Maximov Software Engineer & Starter Twitter: http://twitter.com/maxkir Skype: maxkir http://kirblog.idetalk.com | http://checkvist.com | http://www.jetbrains.com/teamcity -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Mislav Marohnić
2011-Oct-16 15:52 UTC
Re: A proper way to test that database is not accessed?
On Oct 16, 2011, at 8:35 AM, KIR wrote:> ActiveRecord::Base.establish_connection Rails.env > > I don''t quite understand what do you mean here?I know what your problem is. If because of changes to Rails reconnecting to the db by using the old connection doesn''t work, then I suggested that you give up on using the old connection and just instruct AR to connect as if the application was just booting up. Have you tried what I suggested at all? Are you having the same problem? def without_database_connection ActiveRecord::Base.remove_connection begin yield ensure ActiveRecord::Base.establish_connection Rails.env end end -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
> > I know what your problem is. If because of changes to Rails reconnecting to > the db by using the old connection doesn''t work, then I suggested that you > give up on using the old connection and just instruct AR to connect as if > the application was just booting up. Have you tried what I suggested at all? > Are you having the same problem? > > def without_database_connection > ActiveRecord::Base.remove_connection > begin > yield > ensure > ActiveRecord::Base.establish_connection Rails.env > end > end > >Thanks Mislav, I tried your suggestion, but it doesn''t work. My actual problem is not about restoring the connection (but thanks for the tip, I may need it eventually). It is about the fact that I _always_ get exception when I''m trying to access model attributes when connection was removed with remove_connection (i.e. I get exception in the yield part). BTW, have you tried your helper on Rails 3.1.1? Thanks, KIR> -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. >-- Kirill (KIR) Maximov Software Engineer & Starter Twitter: http://twitter.com/maxkir Skype: maxkir http://kirblog.idetalk.com | http://checkvist.com | http://www.jetbrains.com/teamcity -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Mislav Marohnić
2011-Oct-16 17:19 UTC
Re: A proper way to test that database is not accessed?
On Oct 16, 2011, at 6:22 PM, KIR wrote:> BTW, have you tried your helper on Rails 3.1.1?I haven''t tried my code, I just pulled it out of the air. Sorry that I misunderstood your problem – I thought it was about reconnecting. I have the feeling that others also didn''t get what you were saying; people who got notified about your comment on the issue tracker probably thought that you have a problem in your custom helper. The most important thing right now to establish whether this is a real bug or not. The behavior which you relied on before the offending change might not have been intentional. It''s possible that you might be testing wrong things in your application. You should describe what are you doing inside the no connection block. (You mentioned using attribute accessors, but in order to generate these accessors, AR must have an open connection so it can fetch information about table columns.) Describe shortly what you were expecting to get and how the new behavior surprises you and breaks your tests. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
> > You should describe what are you doing inside the no connection block. (You > mentioned using attribute accessors, but in order to generate these > accessors, AR must have an open connection so it can fetch information about > table columns.) Describe shortly what you were expecting to get and how the > new behavior surprises you and breaks your tests. >Basically, I have a test that I don''t have N+1 problem when collecting data. I do something like this: # in the production, this may generate hundreds of items (which have own associations) sub_model_items = model.preload_subitems assert_no_database { json = sub_model_items.build_json } What I''m trying to test - that my code doesn''t perform SQL operations when building json, i.e. all data should be preloaded. Thanks, KIR -- Kirill (KIR) Maximov Software Engineer & Starter Twitter: http://twitter.com/maxkir Skype: maxkir http://kirblog.idetalk.com | http://checkvist.com | http://www.jetbrains.com/teamcity -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Mislav Marohnić
2011-Oct-16 17:58 UTC
Re: A proper way to test that database is not accessed?
On Oct 16, 2011, at 7:42 PM, KIR wrote:> What I''m trying to test - that my code doesn''t perform SQL operations when building json, i.e. all data should be preloaded.That''s a perfectly valid thing to test. Looks like it might be a regression. I suggest that you update the issue (where you commented on) with this information, including your own code related to this and provide a stack trace pasted into a Gist. Until you have a solution for this problem, I suggest testing this another way. In will_paginate, I subscribe to all SQL queries performed and then I check them in tests to see whether there have been too many executed during a particular test. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
> > What I''m trying to test - that my code doesn''t perform SQL operations when > building json, i.e. all data should be preloaded. > > > That''s a perfectly valid thing to test. Looks like it might be a > regression. I suggest that you update the issue (where you commented on) > with this information, including your own code related to this and provide a > stack trace pasted into a Gist. > > Until you have a solution for this problem, I suggest testing this another > way. In will_paginate, I subscribe to all SQL queries performed<https://github.com/mislav/will_paginate/blob/d56a8436/spec/finders/activerecord_test_connector.rb#L5-23> and > then I check them in tests to see whether there have been too many executed > during a particular test. > >Thanks a lot for the hint, will investigate it. May be, I''ll be able to rewrite my assert_no_database assertion using its approach. All the best, KIR> > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. >-- Kirill (KIR) Maximov Software Engineer & Starter Twitter: http://twitter.com/maxkir Skype: maxkir http://kirblog.idetalk.com | http://checkvist.com | http://www.jetbrains.com/teamcity -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
On 17/10/2011, at 08:08 , KIR wrote:> > Thanks a lot for the hint, will investigate it. > May be, I''ll be able to rewrite my assert_no_database assertion using its approach.There''s assert_queries/assert_no_queries in the test case support code, which sound quite similar to what you want. But it needs a subscriber implementation (such as Mislav was talking about for will_paginate), which you need to feed into the global variable that the assertions check. Rails has a subscriber implementation for its own tests, but it isn''t exposed. IMHO it would be great it did, so we could just instantiate that in app test code without having to copy it in (it''s somewhat version-specific). Have a look at activerecord/test/cases/helper.rb to see how it works. The assertions that use it are defined in activerecord/lib/active_record/test_case.rb, so they are exposed, which doesn''t make much sense at the moment. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Will, Mislav, thanks for all your help! I''ve used subscriber to implement my assert_no_database helper. When asserted block of code performs any SQL requests, these requests are included into test output: https://gist.github.com/1305807 Thanks again! KIR On 17 October 2011 04:54, Will Bryant <will.bryant@gmail.com> wrote:> On 17/10/2011, at 08:08 , KIR wrote: > > > > > Thanks a lot for the hint, will investigate it. > > May be, I''ll be able to rewrite my assert_no_database assertion using > its approach. > > There''s assert_queries/assert_no_queries in the test case support code, > which sound quite similar to what you want. But it needs a subscriber > implementation (such as Mislav was talking about for will_paginate), which > you need to feed into the global variable that the assertions check. > > Rails has a subscriber implementation for its own tests, but it isn''t > exposed. IMHO it would be great it did, so we could just instantiate that > in app test code without having to copy it in (it''s somewhat > version-specific). > > Have a look at activerecord/test/cases/helper.rb to see how it works. The > assertions that use it are defined in > activerecord/lib/active_record/test_case.rb, so they are exposed, which > doesn''t make much sense at the moment. > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > >-- Kirill (KIR) Maximov Software Engineer & Starter Twitter: http://twitter.com/maxkir Skype: maxkir http://kirblog.idetalk.com | http://checkvist.com | http://www.jetbrains.com/teamcity -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.