Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I test a ruby Mixin Module?

I'd like to know the best way to approach testing ruby mixin modules, in this case for use with ActiveRecord models, but really this is a general quesiton that applies to any class that you are extending with a mixin.

Is it better to attempt to stub all of the necessary functionality of the Class that your mixin is extending, or just test the real class as present and extended in your app?

Stubbing would remove external dependencies for the tests, but it fails to test the mixin under real circumstances. If the test fail, it could be either your implementation or the class you are extending that changed or broke. If testing with a stubbed class your tests may pass but the functionality could be broken if the class you are extending changes.

Opinions?

like image 539
Daniel Beardsley Avatar asked May 18 '10 20:05

Daniel Beardsley


People also ask

How do you use mixin in Ruby?

Mixins in Ruby allows modules to access instance methods of another one using include method. Mixins provides a controlled way of adding functionality to classes. The code in the mixin starts to interact with code in the class. In Ruby, a code wrapped up in a module is called mixins that a class can include or extend.

How do you call a module method in Rspec?

To call a module method, you specify the name of the module, and the name of the method, separated by a dot. Like this: MyModule. my_method. But you can also include modules into classes so that those classes inherit all the module's instance methods.

What is unit testing in Ruby?

Unit testing is a great way to catch errors early in the development process, if you dedicate time to writing appropriate and useful tests. As in other languages, Ruby provides a framework in its standard library for setting up, organizing, and running tests called Test::Unit.

What are modules Ruby?

A Module is a collection of methods, constants, and class variables. Modules are defined as a class, but with the module keyword not with class keyword. Important Points about Modules: You cannot inherit modules or you can't create a subclass of a module. Objects cannot be created from a module.


1 Answers

It's not completely clear to me what you're asking, but I'm going to assume it's something along the lines of, "If I have a class, and I extend that class with a module, where should I test the functionality provided by the module?"

Personally, when I write a module for use as a mixin, I try to make sure it has fairly robust testing independent of whatever classes I might eventually plan to mix it in to. Typically I'll define a class in the test suite that does nothing but extend to module, and then write tests to ensure that the test class has all the expected functionality. (You can see examples of this in my Classy gem, which is just a collection of mixin modules.) If the module were meant to extend ActiveRecord or some other class I didn't have any control over, I'd define as vanilla an ActiveRecord class as possible and work with that, though ideally I'd try to keep my module's functionality orthogonal from ActiveRecord's when possible.

If changes to ActiveRecord cause your tests to break, then there's a question of what your goals are in writing your module. If you want it to be generally available and useful to the public, then you probably want it to work with the newest version, and those failing tests are accurately reporting bugs that need fixing. If you only want it to work with whatever version you're running locally for your own project, then you can just run the tests against that version and you don't have to worry about it changing.

Assuming I had control over the class being mixed in to, I probably wouldn't test the functionality from the module too extensively in the tests for the class - that's what the module tests are for. I would have a test case or two to make sure that it generally works, and I would test any specific interactions or intricacies specific to the class being tested, and probably leave it at that.

like image 166
John Hyland Avatar answered Sep 23 '22 00:09

John Hyland