Let’s take a closer look at the code of our HelloWorld example. First of all, in case it isn’t clear, we are testing the functionality of the HelloWorld class. This of course, is a very simple class that contains only one method say_hello().
Here is the RSpec code again −
describe HelloWorld do context “When testing the HelloWorld class” do it "The say_hello method should return 'Hello World'" do hw = HelloWorld.new message = hw.say_hello expect(message).to eq "Hello World!" end end end
The word describe is an RSpec keyword. It is used to define an “Example Group”. You can think of an “Example Group” as a collection of tests. The describe keyword can take a class name and/or string argument. You also need to pass a block argument to describe, this will contain the individual tests, or as they are known in RSpec, the “Examples”. The block is just a Ruby block designated by the Ruby do/end keywords.
The context keyword is similar to describe. It too can accept a class name and/or string argument. You should use a block with context as well. The idea of context is that it encloses tests of a certain type.
For example, you can specify groups of Examples with different contexts like this −
context “When passing bad parameters to the foobar() method” context “When passing valid parameters to the foobar() method” context “When testing corner cases with the foobar() method”
The context keyword is not mandatory, but it helps to add more details about the examples that it contains.
The word it is another RSpec keyword which is used to define an “Example”. An example is basically a test or a test case. Again, like describe and context, it accepts both class name and string arguments and should be used with a block argument, designated with do/end. In the case of it, it is customary to only pass a string and block argument. The string argument often uses the word “should” and is meant to describe what specific behavior should happen inside the it block. In other words, it describes that expected outcome is for the Example.
Note the it block from our HelloWorld Example −
it "The say_hello method should return 'Hello World'" do
The string makes it clear what should happen when we call say hello on an instance of the HelloWorld class. This part of the RSpec philosophy, an Example is not just a test, it’s also a specification (a spec). In other words, an Example both documents and tests the expected behavior of your Ruby code.
The expect keyword is used to define an “Expectation” in RSpec. This is a verification step where we check, that a specific expected condition has been met.
From our HelloWorld Example, we have −
expect(message).to eql "Hello World!"
The idea with expect statements is that they read like normal English. You can say this aloud as “Expect the variable message to equal the string ‘Hello World’”. The idea is that its descriptive and also easy to read, even for non-technical stakeholders such as project managers.
The to keyword
The to keyword is used as part of expect statements. Note that you can also use the not_to keyword to express the opposite, when you want the Expectation to be false. You can see that to is used with a dot, expect(message).to, because it actually just a regular Ruby method. In fact, all of the RSpec keywords are really just Ruby methods.
The eql keyword
The eql keyword is a special RSpec keyword called a Matcher. You use Matchers to specify what type of condition you are testing to be true (or false).
In our HelloWorld expect statement, it is clear that eql means string equality. Note that, there are different types of equality operators in Ruby and consequently different corresponding Matchers in RSpec. We will explore the many different types of Matchers in a later section.