My suggestion is to use anonymous classes declared in-line:

# ./spec/foo_spec.rbrequire 'spec_helper'

describe 'Foo' do
  let(:person_class) do
    Class.new(ActiveRecord::Base) do
      has_many :abilities
    end
  end

  it 'has relations' do
    expect(person_class.reflections.keys).to eq %w(abilities)
  endend
# ./spec/bar_spec.rbrequire 'spec_helper'

describe 'Bar' do
  let(:person_class) do
    Class.new(ActiveRecord::Base) do
      has_many :children
    end
  end

  it 'has relations' do
    expect(person_class.reflections.keys).to eq %w(children)
  endend

There are two nice things about this:

   - No cleanup is needed. Since the classes are anonymous, there are no
   constant references to them and once the example completes Ruby’s garbage
   collector will take care of it.
   - There’s no possibility of re-opening an existing class. Class.new
   *always* makes a new class.

The downside is that the class does not have a constant, which might not
play nice with activerecord (it may not support anonymous subclasses) and
it will be less pretty in error messages.

If you want to make it a named class, you can use RSpec’s constant
stubbing; it exists specifically for this:

# ./spec/foo_spec.rbrequire 'spec_helper'

describe 'Foo' do
  before do
    stub_const("Person", Class.new(ActiveRecord::Base) do
      has_many :abilities
    end)
  end

  it 'has relations' do
    expect(Person.reflections.keys).to eq %w(abilities)
  endend
# ./spec/bar_spec.rbrequire 'spec_helper'

describe 'Bar' do
  before do
    stub_const("Person", Class.new(ActiveRecord::Base) do
      has_many :children
    end)
  end

  it 'has relations' do
    expect(Person.reflections.keys).to eq %w(children)
  endend

RSpec will take care of cleaning up the Person constant created in each
example, ensuring the constants do not leak and cause problems.

HTH,
Myron

On Thu, Oct 13, 2016 at 2:49 AM, Jean-Michel Garnier <
jean-mic...@21croissants.com> wrote:

Hi,
>
> Not sure this is the best place, traffic seems quite low these days.
>
> I am wondering what is the best practice to tear down classes declared
> inside `describe` blocks.
> For example:
>
> ```ruby # ./spec/foo_spec.rb require 'spec_helper' describe 'Foo' do class
> Person < ActiveRecord::Base has_many :abilities end it 'has relations' do
> expect(Person.reflections.keys).to eq %w(abilities) end end #
> ./spec/bar_spec.rb require 'spec_helper' describe 'Bar' do class Person <
> ActiveRecord::Base has_many :children end it 'has relations' do
> expect(Person.reflections.keys).to eq %w(children) end end ```
>
> Running each individual file passes but when I run both files then it
> fails (in both files with `["children", "abilities"]` in relations array).
>
> To solve that problem, we use an `after(:all)` block to remove the
> constant with `Object.send(:remove_const, 'Person').
>
> I'd love to hear if other people use that tear down or what is the best
> practice.
>
> Thanks,
>
> JM
>
> --
> 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 post to this group, send email to rspec@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/rspec/8e469a6b-1175-4299-bf99-c90ffd587ca6%40googlegroups.com
> <https://groups.google.com/d/msgid/rspec/8e469a6b-1175-4299-bf99-c90ffd587ca6%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>
​

-- 
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 post to this group, send email to rspec@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/CADUxQmuG7KnUVkDDwFgpv3i8bsuKE_rcsxNN9r8v9seRJyHr5w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to