# Chain Method in Class with Method in Module

**URL:** <https://www.ruby-forum.com/t/chain-method-in-class-with-method-in-module/180042>\
**Category:** Ruby\
**Created:** [December 10, 2009, 5:33am UTC](https://www.ruby-forum.com/t/chain-method-in-class-with-method-in-module/180042 "2009-12-10T05:33:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nappin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f475e1/32.png) [@nappin](https://www.ruby-forum.com/u/nappin)\
**Post date:** [December 10, 2009, 5:33am UTC](https://www.ruby-forum.com/t/chain-method-in-class-with-method-in-module/180042/1 "2009-12-10T05:33:55Z")

</div>

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.

module MyModule  
module InstanceMethods  
def setup  
puts ‘module setup’  
end  
end

def self.included(base)  
base.send :include, InstanceMethods  
end  
end

class MyUnitTest \< Test::Unit::TestCase  
include MyModule

def setup  
puts ‘class setup’  
end

end

If this were working when I run a test in MyUnitTest it should print out  
module setup  
class setup

Unfortunately I can’t get it to work. Even with alias\_method, I run  
into problems it seems because the class setup is defined after the  
module is included. Anyone one have any ideas?

Thanks!

---

<div class="post-metadata">

**Author:** ![nappin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f475e1/32.png) [@nappin](https://www.ruby-forum.com/u/nappin)\
**Post date:** [December 10, 2009, 6:33am UTC](https://www.ruby-forum.com/t/chain-method-in-class-with-method-in-module/180042/2 "2009-12-10T06:33:19Z")

</div>

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. 🙂

---

<div class="post-metadata">

**Author:** ![nappin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f475e1/32.png) [@nappin](https://www.ruby-forum.com/u/nappin)\
**Post date:** [December 10, 2009, 7:54am UTC](https://www.ruby-forum.com/t/chain-method-in-class-with-method-in-module/180042/3 "2009-12-10T07:54:01Z")

</div>

Aaron P. 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.

---

<div class="post-metadata">

**Author:** ![nappin](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f475e1/32.png) [@nappin](https://www.ruby-forum.com/u/nappin)\
**Post date:** [December 10, 2009, 8:36am UTC](https://www.ruby-forum.com/t/chain-method-in-class-with-method-in-module/180042/4 "2009-12-10T08:36:47Z")

</div>

On 10.12.2009 07:55, Raymond O’Connor wrote:

> 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
