From: Robert Klemme Date: 2009-12-10T16:36:07+09:00 Subject: Re: Chain Method in Class with Method in Module On 10.12.2009 07:55, Raymond O'Connor wrote: > Aaron Patterson wrote: >> On Thu, Dec 10, 2009 at 01:33:58PM +0900, Raymond O'Connor wrote: >>> I'd like to chain setup in a unit test, so that it calls a method in a >>> module BEFORE running through the setup code. I'd like to do it without >>> having to put super() in the test's setup method. >> What's wrong with super()? We use it in all of our other objects. >> Tests are normal objects too. :-) > > Trying to keep things as encapsulated as possible. Just seems wrong > that people including the module need to know to call super in setup > before their own setup code. That's the normal way to do business with super classes - and included modules. If you look at MyUnitTest.ancestors you will see that the class is first in the chain and *then* the included module appears. That's why #setup of your class is always invoked before #setup in any included module. Another solution to what you want to do would be this: use the template method pattern. module InstanceMethods def setup puts 'module setup' setup_local end def setup_local raise "Sub class needs to implement this!" end end class MyUnitTest < Test::Unit::TestCase include InstanceMethods def setup_local puts 'class setup' end end Although you can still break the pattern by defining #setup in the class because Ruby does not have final methods (e.g. like Java). Raymond, why do you use two modules here? As far as I can see there is no use case for a second module. Also, you could make InstanceMethods a regular class which inherits Test::Unit::TestCase. Placing this in a module only pays off if you want to include the module in classes which need to have differing super classes. A completely alternative way would be to define a mini DSL where you have full control over what happens: # untested def test(&b) Class.new do def setup puts 'module setup' super end end.send(:include, Module.new(&b)) end MyUnitTest = test do def setup puts 'class setup' end end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/