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