Child < Parent < Test::Unit::TestCase

B

Brian Adkins

I just ran into a problem with Test::Unit exhibited by the two files
below and the output of 'ruby tc_child.rb':

--- tc_child.rb ---
require 'tc_parent'

class ChildTest < ParentTest
def test_one
puts 'test_one called'
assert true
end
end
--- tc_child.rb ---

--- tc_parent.rb ---
require "test/unit"

class ParentTest < Test::Unit::TestCase
def setup
puts 'setup called'
end

def teardown
puts 'teardown called'
end
end
--- tc_parent.rb ---

ruby tc_child.rb
Loaded suite tc_child
Started
setup called
test_one called
teardown called
..setup called
Fteardown called

Finished in 0.004709 seconds.

1) Failure:
default_test(ParentTest) [tc_child.rb:4]:
No tests were specified.

2 tests, 2 assertions, 1 failures, 0 errors
---

So apparently it's inadvisable to insert a class between
Test::Unit::TestCase and a 'leaf node' test class. In my case, I ended
up moving the base functionality into a module that I mixed into
tc_child.rb, and this actually worked better for what I'm trying to
accomplish. The flexibility of modules is a great feature of Ruby.

Is there a way to instruct Test::Unit to not attempt to run tests in
intermediate classes in the hierarchy?

Brian Adkins
 
G

George

Is there a way to instruct Test::Unit to not attempt to run tests in
intermediate classes in the hierarchy?

Hi Brian,

I don't know if it's advisable or not, but one way is to undefine
`default_test'.

require 'test/unit'

class AbstractTestCase < Test::Unit::TestCase
undef_method :default_test
end

class ConcreteTestCase < AbstractTestCase
def test_foo
assert true
end
end

Having said that, unless you really need class inheritance for
something, it's probably cleaner just to #include mixins.

Regards,
George.
 
B

Brian Adkins

Hi Brian,

I don't know if it's advisable or not, but one way is to undefine
`default_test'.

require 'test/unit'

class AbstractTestCase < Test::Unit::TestCase
undef_method :default_test
end

Thanks! I just looked through testcase.rb, and your suggestion seems
to be exactly what I was asking for. I'm satisfied with the mixin
approach for my current scenario, but it's nice to know I have an
option for inheritance if the need arises.

Another option is to just hide the class from ObjectSpace :) I did
some experimenting for the heck of it and came up with the following.
It's just a hack for fun, but can anyone come up with a better way of
passing in the class to be hidden to the redefined each_object method
besides the ugly $cloaked global variable? The fact that the
definition is being evaluated in the scope of the metaclass for
ObjectSpace kind of complicates things.

require "test/unit"

class Module
$cloaked = []
def hide_class
$cloaked << self
end
end

class << ObjectSpace
alias orig_each_object each_object
def each_object(klass)
ObjectSpace.orig_each_object(klass) do |obj|
yield obj if !$cloaked.include?(obj)
end
end
end

class ParentTest < Test::Unit::TestCase
hide_class

def setup
puts 'setup called'
end

def teardown
puts 'teardown called'
end
end
 
B

Brian Adkins

Thanks! I just looked through testcase.rb, and your suggestion seems
to be exactly what I was asking for. I'm satisfied with the mixin
approach for my current scenario, but it's nice to know I have an
option for inheritance if the need arises.

Another option is to just hide the class from ObjectSpace :) I did
some experimenting for the heck of it and came up with the following.
It's just a hack for fun, but can anyone come up with a better way of
passing in the class to be hidden to the redefined each_object method
besides the ugly $cloaked global variable? The fact that the
definition is being evaluated in the scope of the metaclass for
ObjectSpace kind of complicates things.

require "test/unit"

Using a Module class variable helps a bit, but it still doesn't feel
right. Of course, that's likely because it's way too late and my brain
shut off a couple hours ago :(

class Module
def hide_class
Module.cloaked << self
end

def Module.cloaked
@@cloaked ||= []
end
end

class << ObjectSpace
alias orig_each_object each_object
def each_object(klass)
ObjectSpace.orig_each_object(klass) do |obj|
yield obj if !Module.cloaked.include?(obj)
end
end
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top