rspec-given亦是Jim Weirich的作品。given、when、then的引入,让测试变得更方便。
rspec-given的写法十分直接了当:
describe "Character has name" do
Given(:guy) { Character.new("George") }
Then { guy.name.should == "George" }
end
Given
指定测试的预设,Then
指定需要检测的断言。
那么,如果我想更改上面角色的姓名呢?我需要确保更改操作确实有效,这就要用到When
:
describe "Character has name" do
Given(:guy) { Character.new("George") }
Then { guy.name.should == "George" }
describe "changing the name" do
When { guy.name = "Bill" }
Then { guy.name.should == "Bill" }
end
end
来看一个复杂一点的例子吧,测试角色生命值的增减是否有效:
describe "Character can be damaged" do
LOSING_DICE_ROLL = 2
WINNING_DICE_ROLL = 19
CRITICAL_DICE_ROLL = 20
Given(:attacker) { Character.new("Attacker") }
Given(:defender) { Character.new("Defender") }
Given!(:original_hp) { defender.hit_points }
Invariant { defender.should be_alive }
When { attacker.attack(defender, dice_value) }
Given(:change_in_hp) { defenders.hit_points - original_hp }
context "when the attacker misses" do
Given(:dice_value) { LOSING_DICE_ROLL }
Then { change_in_hp.should == 0 }
end
context "when the attacker hits" do
Given(:dice_value) { WINNING_DICE_ROLL }
Then { change_in_hp.should == -1 }
end
context "when the attacker gets a critical hit" do
Given(:dice_value) { CRITICAL_DICE_ROLL }
Then { change_in_hp.should == -2 }
end
end
值得注意的有两点:
我们定义了LOSING_DICE_ROLL
之类的常量,这样设定变更之后只要修改一处。
我们使用了Invariant
,它会在每次执行作用域内的Then
前执行。上面示例中的Invariant
确保生命值增减前角色仍然存活(增减死人的生命值可没有意义)。
上面我们提到了Invariant
针对作用域内的Then
有效,下面给出一个例子:
describe "Character can be damaged" do
LOSING_DICE_ROLL = 2
WINNING_DICE_ROLL = 19
CRITICAL_DICE_ROLL = 20
Given(:attacker) { Character.new("Attacker") }
Given(:defender) { Character.new("Defender") }
Given!(:original_hp) { defender.hit_points }
When { attacker.attack(defender, dice_value) }
Given(:change_in_hp) { defenders.hit_points - original_hp }
context "where the defender survives" do
Invariant { defender.should be_alive }
context "when the attacker misses" do
Given(:dice_value) { LOSING_DICE_ROLL }
Then { change_in_hp.should == 0 }
end
context "when the attacker hits" do
Given(:dice_value) { WINNING_DICE_ROLL }
Then { change_in_hp.should == -1 }
end
context "when the attacker gets a critical hit" do
Given(:dice_value) { CRITICAL_DICE_ROLL }
Then { change_in_hp.should == -2 }
end
end
context "where the defender dies" do
Given { defender.takes_damage(defender.hit_points - 1) }
When { attacker.attack(defender, 19) }
Then { defender.should be_dead }
end
end
上述代码中,Invariant
只在where the defender survives
上下文中生效。
撰文 SegmentFault
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。