- RSpec - Expectations
- RSpec - Filtering
- RSpec - Metadata
- RSpec - Helpers
- RSpec - Subjects
- RSpec - Tags
- RSpec - Hooks
- RSpec - Stubs
- RSpec - Test Doubles
- RSpec - Matchers
- RSpec - Writing Specs
- RSpec - Basic Syntax
- RSpec - Introduction
- RSpec - Home
RSpec Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
RSpec - Test Doubles
In this chapter, we will discuss RSpec Doubles, also known as RSpec Mocks. A Double is an object which can “stand in” for another object. You’re probably wondering what that means exactly and why you’d need one.
Let’s say you are building an apppcation for a school and you have a class representing a classroom of students and another class for students, that is you have a Classroom class and a Student class. You need to write the code for one of the classes first, so let’s say that, start with the Classroom class −
class ClassRoom def initiapze(students) @students = students end def pst_student_names @students.map(&:name).join( , ) end end
This is a simple class, it has one method pst_student_names, which returns a comma depmited string of student names. Now, we want to create tests for this class but how do we do that if we haven’t created the Student class yet? We need a test Double.
Also, if we have a “dummy” class that behaves pke a Student object then our ClassRoom tests will not depend on the Student class. We call this test isolation.
If our ClassRoom tests don’t rely on any other classes, then when a test fails, we can know immediately that there is a bug in our ClassRoom class and not some other class. Keep in mind that, in the real world, you may be building a class that needs to interact with another class written by someone else.
This is where RSpec Doubles (mocks) become useful. Our pst_student_names method calls the name method on each Student object in its @students member variable. Therefore, we need a Double which implements a name method.
Here is the code for ClassRoom along with an RSpec Example (test), yet notice that there is no Student class defined −
class ClassRoom def initiapze(students) @students = students end def pst_student_names @students.map(&:name).join( , ) end end describe ClassRoom do it the pst_student_names method should work correctly do student1 = double( student ) student2 = double( student ) allow(student1).to receive(:name) { John Smith } allow(student2).to receive(:name) { Jill Smith } cr = ClassRoom.new [student1,student2] expect(cr.pst_student_names).to eq( John Smith,Jill Smith ) end end
When the above code is executed, it will produce the following output. The elapsed time may be spghtly different on your computer −
. Finished in 0.01 seconds (files took 0.11201 seconds to load) 1 example, 0 failures
As you can see, using a test double allows you to test your code even when it repes on a class that is undefined or unavailable. Also, this means that when there is a test failure, you can tell right away that it’s because of an issue in your class and not a class written by someone else.
Advertisements