Testing Ruby Mixins with Minitest in isolation

Posted by Ilija Eftimov on November 4, 2015

Mixins in Ruby are a very powerful feature. But knowing how to test them sometimes
is not so obvious, especially to beginners. I think that this comes from mixins’
nature - they get mixed into other classes. So, if you think that there is a lot
to testing mixins and you easily get overwhelmed by it - take it easy, it’s not
that hard.

Let’s see how easy it is to test mixins, with some help from the lovely Minitest.

Mixins

When writing Ruby, we usually write two types of mixins. The first one is a coupled
mixin, and the other, well.. uncoupled.

Uncoupled mixins

Uncoupled mixins are the ones whose methods do not depend on the implementation
of the class where they will get mixed in.

As you can see, we instantiate an object of the Object class which is just
an empty, ordinary object that doesn’t do anything. Then, we extend the object
singleton class with the Speedable module which will mix the speed method in.
Then, in the test, we assert that the method will return the expected output.

As you can see, we create just a dummy class, specific only for this test file.
Since the FastCar mixin is mixed in, the DummyTestClass will have the
speed method as an instance method. Then, in the test, we just create a new
object from the dummy class and assert on the dummy.speed method.

Coupled mixins

Coupled mixins are the ones whose methods depend on the implementation of the class
where they will be mixed in. Or, the oposite of uncoupled mixins.

You see, the implementation of the Reportable#report method relies on
(or, is coupled to) the implementation of the DieselCar and PetrolCar
classes. If we mixed in the Reportable mixin in a class that does not have the
fuel method implemented, we would get an error when calling the report method.

Testing coupled mixins

When it comes to coupled mixins, testing can get just a tad bit harder. Again, the same two
strategies.

Now, this is cleaner. We create a DummyCar class where we mix the Reportable
mixin and we define the fuel method. Then, in the test, we just create a
DummyCar object and we assert for the value of the report method. Remember,
we are doing this only because we want to test the mixin. If we were to test any of
the classes, there would be no point in doing this.

As you can see, it’s quite simple to test these mixins with plain-old Ruby. I guess
it’s worth mentioning that these examples are very simple and you might run into
more complex mixins that need testing in the future. But, when testing mixins,
these strategies will still work. Just don’t get owerwhelmed and take it step-by-step.