views:

29

answers:

1

I have a number of models that use STI and I would like to use the same unit test to test each model. For example, I have:

class RegularList < List
class OtherList < List

class ListTest < ActiveSupport::TestCase
  fixtures :lists

  def test_word_count
    list = lists(:regular_list)
    assert_equal(0, list.count)
  end

end

How would I go about using the test_word_count test for the OtherList model. The test is much longer so I would rather not have to retype it for each model. Thanks.

EDIT: I am trying to use a mixin as per Randy's suggestion. This is what I have but am getting the error: "Object is not missing constant ListTestMethods! (ArgumentError)":

in lib/list_test_methods.rb:

module ListTestMethods
  fixtures :lists

  def test_word_count 
    ...
  end
end

in regular_list_test.rb:

require File.dirname(__FILE__) + '/../test_helper'

class RegularListTest < ActiveSupport::TestCase
  include ListTestMethods

  protected  
  def list_type
    return :regular_list
  end
end

EDIT: Everything seems to work if I put the fixtures call in the RegularListTest and remove it from the module.

+1  A: 

I actually had a similar problem and used a mixin to solve it.

module ListTestMethods

  def test_word_count
    # the list type method is implemented by the including class
    list = lists(list_type)
    assert_equal(0, list.count)
  end

end

class RegularListTest < ActiveSupport::TestCase
  fixtures :lists

  include ::ListTestMethods

  # Put any regular list specific tests here

  protected 

  def list_type
    return :regular_list
  end
end

class OtherListTest < ActiveSupport::TestCase
  fixtures :lists

  include ::ListTestMethods

  # Put any other list specific tests here

  protected 

  def list_type
    return :other_list
  end
end

What works well here is that OtherListTest and RegularListTest are able to grow independently of each other.

Potentially, you could also do this with a base class but since Ruby does not support abstract base classes it isn't as clean of a solution.

Randy Simon
Is there any way to use this setup to call individual methods from the ListTestMethods module within a test? I have some methods that overlap and others that do not and I would rather not make another module file.
TenJack
I'm not sure I understand your question here. Can you give an example? From a mixin you can call methods in your including class. In the case above the mixin calls the list_type method on OtherListTest and RegularListTest. In addition, your including class can call methods on the mixin.
Randy Simon