RSPEC中Expect和should表达式的示例
来源:互联网 发布:成都 大数据 招聘 编辑:程序博客网 时间:2024/06/05 04:01
EXPECT Basic usage
Here’s an example using rspec-core:
rubyRSpec.describe Order do it "sums the prices of the items in its line items" do order = Order.new order.add_entry(LineItem.new(:item => Item.new( :price => Money.new(1.11, :USD) ))) order.add_entry(LineItem.new(:item => Item.new( :price => Money.new(2.22, :USD), :quantity => 2 ))) expect(order.total).to eq(Money.new(5.55, :USD)) endend
The describe
and it
methods come from rspec-core. TheOrder
,LineItem
, Item
and Money
classes would be fromyour code. The last line of the exampleexpresses an expected outcome. Iforder.total == Money.new(5.55, :USD)
, thenthe example passes. If not, it fails with a message like:
expected: #<Money @value=5.55 @currency=:USD> got: #<Money @value=1.11 @currency=:USD>
Built-in matchers
Equivalence
ruby
expect(actual).to eq(expected) # passes if actual == expected
expect(actual).to eql(expected) # passes if actual.eql?(expected)
expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected))
Note: The new expect
syntax no longer supports the==
matcher.
Identity
ruby
expect(actual).to be(expected) # passes if actual.equal?(expected)
expect(actual).to equal(expected) # passes if actual.equal?(expected)
Comparisons
ruby
expect(actual).to be > expected
expect(actual).to be >= expected
expect(actual).to be <= expected
expect(actual).to be < expected
expect(actual).to be_within(delta).of(expected)
Regular expressions
ruby
expect(actual).to match(/expression/)
Note: The new expect
syntax no longer supports the=~
matcher.
Types/classes
ruby
expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected
expect(actual).to be_a(expected) # passes if actual.is_a?(expected)
expect(actual).to be_an(expected) # an alias for be_a
expect(actual).to be_a_kind_of(expected) # another alias
Truthiness
ruby
expect(actual).to be_truthy # passes if actual is truthy (not nil or false)
expect(actual).to be true # passes if actual == true
expect(actual).to be_falsy # passes if actual is falsy (nil or false)
expect(actual).to be false # passes if actual == false
expect(actual).to be_nil # passes if actual is nil
expect(actual).to_not be_nil # passes if actual is not nil
Expecting errors
ruby
expect { ... }.to raise_error
expect { ... }.to raise_error(ErrorClass)
expect { ... }.to raise_error("message")
expect { ... }.to raise_error(ErrorClass, "message")
Expecting throws
ruby
expect { ... }.to throw_symbol
expect { ... }.to throw_symbol(:symbol)
expect { ... }.to throw_symbol(:symbol, 'value')
Yielding
```rubyexpect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args
expect {byield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yieldedexpect {b5.tap(&b) }.to yield_with_args(5)expect {b5.tap(&b) }.to yield_with_args(Fixnum)expect {b“a string”.tap(&b) }.to yield_with_args(/str/)expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])```
Predicate matchers
ruby
expect(actual).to be_xxx # passes if actual.xxx?expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg)
Ranges (Ruby >= 1.9 only)
ruby
expect(1..10).to cover(3)
Collection membership
```ruby
expect(actual).to include(expected)
expect(actual).to start_with(expected)
expect(actual).to end_with(expected)
expect(actual).to contain_exactly(individual, items)# …which is the same as:expect(actual).to match_array( expected_array ) ```
Examples
ruby
expect([1, 2, 3]).to include(1)
expect([1, 2, 3]).to include(1, 2)
expect([1, 2, 3]).to start_with(1)
expect([1, 2, 3]).to start_with(1, 2)
expect([1, 2, 3]).to end_with(3)
expect([1, 2, 3]).to end_with(2, 3)
expect({:a => 'b'}).to include(:a => 'b')
expect("this string").to include("is str")
expect("this string").to start_with("this")
expect("this string").to end_with("ring")
expect([1, 2, 3]).to contain_exactly(2, 3, 1)
expect([1, 2, 3]).to match_array([3, 2, 1])
Compound Matcher Expressions
You can also create compound matcher expressions usingand
oror
:
ruby
expect(alphabet).to start_with("a").and end_with("z")
expect(stoplight.color).to eq("red").or eq("green").or eq("yellow")
Composing Matchers
Many of the built-in matchers are designed to take matchers asarguments, to allow you to flexibly specify only the essentialaspects of an object or data structure. In addition, all of thebuilt-in matchers have one or more aliases that provide betterphrasing for when they are used as arguments to another matcher.
Examples
```ruby
expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) )
expect { s = “barn” }.to change { s } .from( a_string_matching(/foo/) ) .to( a_string_matching(/bar/) )
expect([“barn”, 2.45]).to contain_exactly( a_value_within(0.1).of(2.5), a_string_starting_with(“bar”))
expect([“barn”, “food”, 2.45]).to end_with( a_string_matching(“foo”), a_value > 2)
expect([“barn”, 2.45]).to include( a_string_starting_with(“bar”) )
expect(:a => “food”, :b => “good”).to include(:a => a_string_matching(/foo/))
hash = { :a => { :b => [“foo”, 5], :c => { :d => 2.05 } }}
expect(hash).to match( :a => { :b => a_collection_containing_exactly( a_string_starting_with(“f”), an_instance_of(Fixnum) ), :c => { :d => (a_value < 3) } })
expect { |probe| [1, 2, 3].each(&probe)}.to yield_successive_args( a_value < 2, 2, a_value > 2 )```
Usage outside rspec-core
You always need to load rspec/expectations
even if you only want to use one part of the library:
ruby
require 'rspec/expectations'
Then simply include RSpec::Matchers
in any class:
```ruby
class MyClass include RSpec::Matchers
def do_something(arg)
expect(arg).to be > 0
# do other stuff
end
end```
should
and should_not
syntax
From the beginning RSpec::Expectations provided should
and should_not
methodsto define expectations on any object. In version 2.11expect
method wasintroduced which is now the recommended way to define expectations on an object.
Why switch over from should
to expect
Fix edge case issues
should
and should_not
work by being added to every object. However, RSpecdoes not own every object and cannot ensure they work consistently on every object.In particular, they can lead to surprising failures when used with BasicObject-subclassedproxy objects.
expect
avoids these problems altogether by not needing to be available on all objects.
Unification of block and value syntaxes
Before version 2.11 expect
was just a more readable alternative for blockexpectations. Since version 2.11expect
can be used for both block and valueexpectations.
expect(actual).to eq(expected)expect { ... }.to raise_error(ErrorClass)
Seehttp://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntaxFor a detailed explanation
One-liners
The one-liner syntax supported byrspec-core usesshould
even whenconfig.syntax = :expect
. It reads better than the alternative, and does notrequire a global monkey patch:
describe User do it { should validate_presence_of :email }end
Using either expect
or should
or both
By default, both expect
and should
syntaxes are available. In the future,the default may be changed to only enable theexpect
syntax.
If you want your project to only use any one of these syntaxes, you can configureit:
RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = :expect # disables `should` # or c.syntax = :should # disables `expect` # or c.syntax = [:should, :expect] # default, enables both `should` and `expect` endend
SeeRSpec::Expectations::Syntax#expectfor more information.
Usage
The should
and should_not
methods can be used to define expectations on anyobject.
actual.should eq expectedactual.should be > 3[1, 2, 3].should_not include 4
Using Built-in matchers
Equivalence
actual.should eq(expected) # passes if actual == expectedactual.should == expected # passes if actual == expectedactual.should_not eql(expected) # passes if actual.eql?(expected)
Note: we recommend the eq
matcher over==
to avoid Ruby's "== in auseless context" warning when the==
matcher is used anywhere but thelast statement of an example.
Identity
actual.should be(expected) # passes if actual.equal?(expected)actual.should_not equal(expected) # passes if actual.equal?(expected)
Comparisons
actual.should be > expectedactual.should be >= expectedactual.should be <= expectedactual.should be < expectedactual.should be_within(delta).of(expected)
Regular expressions
actual.should match(/expression/)actual.should =~ /expression/
Types/classes
actual.should be_an_instance_of(expected)actual.should_not be_a_kind_of(expected)
Truthiness
actual.should be_true # passes if actual is truthy (not nil or false)actual.should be_false # passes if actual is falsy (nil or false)actual.should be_nil # passes if actual is nil
Predicate matchers
actual.should be_xxx # passes if actual.xxx?actual.should_not have_xxx(:arg) # passes if actual.has_xxx?(:arg)
Ranges (Ruby >= 1.9 only)
(1..10).should cover(3)
Collection membership
actual.should include(expected)actual.should start_with(expected)actual.should end_with(expected)
Examples
[1,2,3].should include(1)[1,2,3].should include(1, 2)[1,2,3].should start_with(1)[1,2,3].should start_with(1,2)[1,2,3].should end_with(3)[1,2,3].should end_with(2,3){:a => 'b'}.should include(:a => 'b')"this string".should include("is str")"this string".should start_with("this")"this string".should end_with("ring")相较来说应该使用expect更多一些。原因: 因为expect
的实现侵入性比较低,expect
方法会返回一个代理对象,上面绑定了一些可以用来进行断言的方法。
而should
的实现是将should
一类的方法直接注入到所有的对象里,破坏性比较高。如果你自己定义了一些和
should
一类同名的方法就悲剧了。
require ‘spec_helper’:目的是加载’spec/spec_helper.rb’文件中的RSpec配置,运行时需要。
describe()方法:
我们用describe()方法定义一个测试用例组,describe()方法的参数可以是我们要测试的对象(如例中的People),可以是一个字符串,用来描述该组,describe方法后的字符串所描述的内容可以对应一个用户故事。
注意describe()方法是可以嵌套的,两个describe()方法衔接起来可以更细化一个用户故事,如上边的里面的describe()方法内就表示:”People have enough money pay for house”。
it()方法:
我们用it()方法定义一个具体的测试用例(在RSpec中,称一个测试用例为一个example)。其后的字符串为该方法的参数,用来描述一个具体的场景,it方法体就是我们对系统在该场景下的行为的定义。
It()方法和describe()方法衔接起来,可以完整的描述一个系统行为,以上边的最后的一个测试用例为:”People have enough money pay for house should travel ”。
context()方法:
Context()方法和describe()方法的作用一样,不同点在于describe倾向于描述我们的测试对象,而context()方法倾向于用字符串描述用户故事。
before()和after():
这两个方法很多测试框架都支持,需要说明的是这两个方法的参数,例子中为符号’:each’,表明对于每一个测试用例,先执行 before()方法中的代码,用例完成后执行after()方法中的代码,若参数为’:all’,则表示在所有的测试用例执行之前,先执行 before()方法中的代码,所有的用例完成后执行after()方法中的代码。
RSpec还提供around()方法,暂不懂其用法,之后的报告中补上。
帮助方法:
所谓的帮助方法就是把多个测试用例中重复的操作抽出作为一个公用的方法,提高代码重用度。如例子中的work_hard()方法。
共享行为:
系统的某一个行为是很多场景下都具有的,那么我们可以把它定义为一个共享行为,我们通过share_examples_for()方法 定义共享行为,使用it_behaves_like()方法共享定义过的系统行为,如例子中的share_examples_for “any people”, it_behaves_like “any people”。
pending()方法:
我们确定系统拥有一个行为,但是还没有具体定义,这时我们可以将该行为使用pending()方法来设置该行为为待定义,其后的字符串参数将在生成的报告中显示。
pending()方法的另外一种用法就是,当一个测试用例失败时,我们可以利用pending方法设置其为一个待修复的bug,方法体内包含使用例失败的代码。例如最后一个测试用例的内容
The rspec-core gem installs an rspec
executable. Run therspec
command with
the --help
flag to see the available options:
rspec --help
Getting started
Begin with a very simple example that expresses some basic desired behaviour.
# game_spec.rbRSpec.describe Game do describe "#score" do it "returns 0 for an all gutter game" do game = Game.new 20.times { game.roll(0) } expect(game.score).to eq(0) end endend
Run the example and watch it fail.
$ rspec game_spec.rb uninitialized constant Object::Game (NameError)
Now write just enough code to make it pass.
# game_spec.rbrequire './game'...
# game.rbclass Game def roll(pins) end def score 0 endend
Run the example and bask in the joy that is green.
$ rspec game_spec.rb --color --format docGame #score returns 0 for all gutter gameFinished in 0.00057 seconds1 example, 0 failures
- RSPEC中Expect和should表达式的示例
- RSpec::Mocks中allow和allow_any_instance_of的区别
- SHELL-expect、正则表达式和sed的使用
- 项目开发中,快速增加 Rspec的支持, 快速增加 spork 和 guard 的支持
- javascript中解析四则运算表达式的算法和示例
- expect中interact和expect eof使用的一些小问题
- rails rspec中安装和配置database cleaner
- C++中expect的使用(ssh 和 scp)
- Rails中rspec测试xxx_path调用失败的解决
- linux中expect的使用
- RSpec
- rspec
- RSpec
- rspec
- Linux 中 TCL 和 Expect语法
- 说说rspec测试的使用
- 对rspec的“才知道”
- [基础]Ruby中使用Rspec 和Rake(非Rails环境)
- 数据挖掘算法——关联规则挖掘算法
- 图片缩略
- 【好程序员笔记分享】——时间处理
- 黑马程序员_日记56_Map概述和简单方法
- 随机目录,文件夹,文件名
- RSPEC中Expect和should表达式的示例
- 第六周 项目6-3 复数类模板
- 配置spring的配置list,map,set,props集合属性
- VC对话框控件基本操作1
- 【《软件设计模式与体系结构》学习笔记】软件设计模式概论
- 4 Facts About Decision Making That Will Improve Conversion Rate Optimization
- break语句的用法总结
- 《C语言及程序设计》实践参考——大奖赛计分(续一)
- Java反射机制详解