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.
When writing Ruby, we usually write two types of mixins. The first one is a coupled mixin, and the other, well.. uncoupled.
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, the
speed method in the
Speedable mixins does not depend on
any other methods. In other words, it’s self-contained.
Testing uncoupled mixins
When it comes to testing uncoupled mixins, it’s quite trivial. There are two main strategies that you can use, by extending the singleton class of an object or by using a dummy class.
Let’s see the first one.
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
in. Then, in the test, we assert that the method will return the expected
The second strategy is the “dummy class” strategy:
As you can see, we create just a dummy class, specific only for this test file.
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
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.
Let me show you a quick example:
Now, if we try our classes in
You see, the implementation of the
Reportable#report method relies on (or, is
coupled to) the implementation of the
PetrolCar classes. If
we mixed in the
Reportable mixin in a class that does not have the
method implemented, we would get an error when calling the
Testing coupled mixins
When it comes to coupled mixins, testing can get just a tad bit harder. Again, the same two strategies.
Now, you can see, it gets a bit hairy when we open the singleton class of the
@test_obj and we add the
fuel method, so our coupled mixin can work. But,
otherwise, it’s quite straight forward.
The approach that I prefer is using the dummy class because it’s much more explicit.
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
DummyCar object and we assert for the value of the
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.