Hello everyone,
I’m quite new to Ruby, with a strong background in PHP.
I had a great time finding my way around in Ruby, because it is a
fantastic language. However, right now I’m a bit stuck regarding the
issue of loose coupling / inversion of control / writing testable units.
I spent the last days reading a lot of articles, but feel sort of
puzzled now.
As far as I can see, there are several approaches. I will start with my
own, which probably is the weirdest of all - feel free to dissect it.
Let’s say I have 2 classes, SomeClass and OtherClass, and SomeClass
depends on OtherClass, because in some cases it needs to create an
instance of this class, and in others it doesn’t, which is why we can’t
simply pass an already created instance of OtherClass into SomeClass.
This is how it could be done using no DI at all:
class SomeClass
def do_something(a, b)
c = a + b
if (c > 5) then
o = OtherClass.new()
o.log©
end
end
end
s = SomeClass.new
s.do_something(1, 2)
Which of course doesn’t allow me to replace “o” with a mock object for
testing etc.
This is how it might be done using the fact that ruby classes are
objects (my approach):
class SomeClass
def do_something(a, b, logObjectClass)
c = a + b
if (c > 5) then
o = logObjectClass.new()
o.log©
end
end
end
s = SomeClass.new
s.do_something(1, 2, OtherClass)
This way, I can inject into SomeClass which class to actually use - as
long as whatever I pass using logObjectClass supports the expected
protocol, all should be fine. I could easily inject a mock log object
for my tests.
But, I couldn’t find any articles recommending this approach, and I
guess there’s a reason for that…
Another solution which seems to be more along “the Ruby way” is this:
class SomeClass
def do_something(a, b)
c = a + b
if (c > 5) then
o = get_logger()
o.log©
end
end
def get_logger()
OtherClass.new()
end
end
// Replacing with mock object:
s = SomeClass.new
def s.get_logger()
MockLoggerClass.new()
end
s.do_something(1, 2)
Could someone help me to understand which approach is better, and why?
Or if maybe I’m getting it completely wrong?
Thanks in advance,