I have an ActiveRecord model which has some callbacks and custom validations I want to test. It means, that I have to make all of them public. Is that a good practice or is there a better solution in this case?
Examples of the methods I want to test:
def before_validation
original.edit(self) if original
end
validate :unique?, on: :create
def unique?
return true if original.blank?
errors.add(:base, 'The entry already exists')
false
end
In other words:
- If I want to test “before_validation” method, do I have to make it public and call test_object.before_validation directly in my model Rspec file?
- If I want to test not only, that custom validation method unique?() is called on validation, but also, the method itself, do I have to make the unique?() public as well?
The problem is, that neither of these methods I am using outside my of model (so they they should be private), but how could I test without making them public?
It’s easy to get caught up in testing implementation, but this is a good candidate for testing behaviour.
Ask yourself, what is your before validation really doing? Then make yourself a test that, given certain inputs, you’ll get certain outputs if and only if your before validation works.
As a simple example, imagine you have a user model with a simple
nameattribute, and you have a before_validation that simply does:Then you could write a test for it like this:
So as you can see, this test does test the validation, but it doesn’t need it to be public, because you’re just testing the behaviour of it. The same goes for your
unique?method. Give it certain inputs and test the behaviour, without having to care about which specific method was used or any other implementation details.