Recently, I was creating a small project to play around with new concepts I had learned for RSpec testing in Ruby and realized something. How exactly do I test an instance(or class!) method in one model that relies on the result of a method from a different model entirely.

I’ll give you my basic example. I had a User model and a Pet model, whereby the Pet belonged to the User. Just to grasp the concept of how to interweave models in testing, I created a simple method on the User model called #pet_animal and gave it a simple output of true. I then wanted to create a method in the Pet model called #be_happy whereby, if the output of #pet_animal was equal to true in the owner instance parameter, then the animal would return “Purr”. Forgive the incredibly rudimentary methods especially if they don’t make much sense. This was more to understand doubles et al.

Here was the really basic setup!

Image for post

So, in the test folder for Pets. I needed to recreate an owner instance to allow me to test the #be_happy method. The first option was creating a double.

Doubles

A double would simulate a User object. This allows you simplify the process. If the business logic to achieve true in our #pet_animal method was significant, then the tests would take longer and also may not return what we actually want to test! Instead we can by-pass this and set the method to true automatically in our double. Allowing us to test the Pet #be_happy method.

Image for post

Simple double test

Here we have used the let method to set the double we have created to the variable :owner. We have then used the double method to set pet_animal to true.

Next, we need to create an instance of our Pet so that we can call the necessary method!

#rspec #ruby-on-rails #ruby #testing

Doubles, Instance Doubles, and Spies in RSpec
1.30 GEEK