Thanks, Jon. I'll have a look at what rspec-rails does but I guess I am going to have to set up the set of models for the whole set. I was hoping to avoid this so that the configuration being tested could be kept near the tests but perhaps I am trying to stretch Rails too much.
Regards, Joe On Tuesday, 27 July 2021 at 19:50:35 UTC+1 ma...@jonrowe.co.uk wrote: > Hello! > > Its likely that you are confusing Rails here, it generally doesn't (pardon > the pun) expect models to be dynamically created and thus may well be > keeping things around. > > I can suggest two alternative strategies, one is set up a temporary set of > models for the entire test run that don't change, another is to generate a > new rails app each time you need to and shell out to it, we do something > similar within rspec-rails to smoke test various integrations. > > I can confirm that your constants would be cleared up, but theres no magic > within RSpec to ensure there are no references to those classes other than > their constants, thats a bit beyond our reach. > > Cheers > Jon > > On Tue, 27 Jul 2021, at 3:56 PM, Joseph Haig wrote: > > I am attempting to refactor the tests in the amoeba gem ( > https://github.com/amoeba-rb/amoeba) with a view to being able to fix > some bugs and (possibly) add new features. > > The tests require ActiveRecord models with associations (has_one, > has_many, etc) and for the existing tests these are defined all together in > one place for the whole suite but, for me, this makes it hard to understand > what features are tested in each unit test. I would therefore like to > create temporary models with each test, and I can do that as follows: > > ``` > # Create the tables in the database > ActiveRecord::Base.connection.drop_table :parents, if_exists: true > ActiveRecord::Base.connection.drop_table :children, if_exists: true > ActiveRecord::Base.connection.create_table :parents > ActiveRecord::Base.connection.create_table :children do |t| > t.references :parent > end > > # Stub models (so that they are discarded after the tests) > stub_const 'Parent', Class.new(ActiveRecord::Base) > stub_const 'Child', Class.new(ActiveRecord::Base) > > # Configure the models, as required > Parent.class_eval 'has_one :child' > ``` > > This works OK but I have a problem if I try to use the same temporary > model names with a different association type. Here is an example: > > ``` > require 'spec_helper' > > RSpec.describe 'testing' do > before do > ActiveRecord::Base.connection.drop_table :parents, if_exists: true > ActiveRecord::Base.connection.drop_table :children, if_exists: true > ActiveRecord::Base.connection.create_table :parents > ActiveRecord::Base.connection.create_table :children do |t| > t.references :parent > end > > stub_const 'Parent', Class.new(ActiveRecord::Base) > stub_const 'Child', Class.new(ActiveRecord::Base) > end > > describe 'has_one' do > subject(:record) { Parent.create(child: Child.new) } > > before do > Parent.class_eval 'has_one :child, inverse_of: :parent' > Child.class_eval 'belongs_to :parent, inverse_of: :child' > end > > it { expect { record }.not_to raise_error } > end > > describe 'has_many' do > subject(:record) { Parent.create(children: [Child.new]) } > > before do > Parent.class_eval 'has_many :children, inverse_of: :parent' > Child.class_eval 'belongs_to :parent, inverse_of: :children' > end > > it { expect { record }.not_to raise_error } > end > end > ``` > > The Parent model in the first case has a 'has_one' association and in the > second case there is a 'has_many' association. The test in each case checks > that an instance can be created. When running each individually (`rspec > spec/test_spec.rb:24` and `rspec spec/test_spec.rb:35`) they both pass but > when run together I get: > > expected no Exception, got > #<ActiveRecord::InverseOfAssociationNotFoundError: Could not find the > inverse association for parent (:children in Parent)> with backtrace: > > with the second test. This suggests to me that the tests are not correctly > isolated, and the configuration of the first is affecting the second. I had > hoped that the stubbed constants for the models would ensure that all > configuration is discarded but is there some sort of cache in ActiveRecord > that needs to be cleared? Or maybe what I'm doing is crazy? > > Thanks, > > Joe > > > -- > You received this message because you are subscribed to the Google Groups > "rspec" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rspec+un...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/rspec/CAKRXwc0J5pTcJnb-01tE8Nq8iS9e8y4grOMqf_vabidC2w-tDw%40mail.gmail.com > > <https://groups.google.com/d/msgid/rspec/CAKRXwc0J5pTcJnb-01tE8Nq8iS9e8y4grOMqf_vabidC2w-tDw%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > > > -- You received this message because you are subscribed to the Google Groups "rspec" group. To unsubscribe from this group and stop receiving emails from it, send an email to rspec+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/954f53cf-ea24-468b-96a2-e19c48a0ad08n%40googlegroups.com.