Reputation: 11659
I am just trying to understand the basics behind unit testing. I wrote a Player class in a file called Player.rb. Here is the code:
Class Player
attr_reader :health
attr_accessor :name
def initialize(name, health=100)
@name = name.capitalize
@health = health
end
def blam
@health -= 10
puts "#{@name} just got blammed yo."
end
def w00t
@health += 15
puts "#{@name} just got w00ted."
end
def score
@health + @name.length
end
def name=(new_name)
@name = new_name.capitalize
end
def to_s
puts "I'm #{@name} with a health of #{@health} and a score of #{score}"
end
end
Here is my spec file:
require_relative 'Player'
describe Player do
it "has a capitalized name" do
player = Player.new("larry", 150)
player.name.should == "Larry"
end
end
Does that seem about right? My question is in regards to the syntax of the spec file. I understand why I need to require the Player class. But what is the describe and it sections of the code doing? Why do I need the it section? All it seems to be doing is defining a string right?
Finally, when I run rspec player_spec.rb from Terminal, I get this warning:
Deprecation Warnings:
Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` instead. Called from /Users/Jwan/studio_game/player_spec.rb:7:in `block (2 levels) in <top (required)>'.
What does the above warning mean? Do I have to replace should with enable syntax? How do I enable the :should syntax? Why is :should written as a symbol?
Upvotes: 1
Views: 1213
Reputation: 102250
it
sets up an actual example. An example can be thought of as an actual test which contains one or more expectations (best practice says one expectation per example).
The expect
method and matchers only exist in the it
block. Variables set up with let
and subject
are unique for each example.
scenario
is an alias for it
used in feature (acceptance) specs.
describe
, context
and feature
are used to group examples together. This provides both readability and encapsulation for let
and subject
variables.
Passing a class to describe
also sets up an implicit subject:
RSpec.describe Array do
describe "when first created" do
it { is_expected.to be_empty }
end
end
RSpec has relativly recently undergone a large shift towards eliminating "monkey patching" core ruby classes which depreciated the should
syntax.
While it is recommended to use expect
for new projects, you can allow should
and other monkey patching methods.
Upvotes: 2
Reputation: 106087
Yes, that seems about right. One thing you might find useful is to use subject
, which lets you define a "subject" to use in multiple tests:
describe Player do
subject { Player.new("larry", 150) }
it "has a capitalized name" do
expect(subject.name).to eq "Larry"
end
end
This way you don't have to define player
over and over again in every test—subject
will automatically initialize it for you each time.
describe
and it
are primarily for organization. A large project will ultimately have thousands of tests, and a change in one class might cause a test to fail for a completely different part of application. Keeping tests organized makes it much easier to find and fix errors as they occur.
As for your warning, it looks like you're using an old guide or tutorial that tells you to use "should" syntax, but in RSpec 3 this syntax is deprecated and "expect" syntax is required instead. You can see how I changed your code above to use "expect" syntax. Here's a good blog post on the new syntax (and why the old syntax is deprecated).
Upvotes: 6