OSDN Git Service

Regular updates
[twpd/master.git] / rspec.md
1 ---
2 title: RSpec
3 category: Ruby
4 layout: 2017/sheet
5 ---
6
7 ### About
8 {: .-intro}
9
10 RSpec is a Ruby library for testing.
11
12 - <https://rspec.info/>
13
14 ### Invoking tests
15
16 ```sh
17 rake -T spec      # List spec tasks
18
19 rake spec         # Run all
20
21 rake spec/models/mymodel_spec.rb
22 rake spec/models/mymodel_spec.rb:27
23 ```
24
25 ## Writing tests
26
27 ```rb
28 describe "A User (in general)" do
29   include UserSpecHelper
30
31   subject { Person.new }
32
33   let(:admin) { Person.new(role: :admin) }
34
35   context "setter methods" do
36     it "should do this" do
37       pending "some other thing"
38
39       expect(subject.name).to eq 'x'
40     end
41   end
42 end
43 ```
44
45 ### Before/after
46
47 ```rb
48 before :each do
49   # before all tests
50 end
51
52 before do
53   # before this suite
54 end
55
56 after do
57   # after this suite
58 end
59 ```
60
61 ### Subjects
62
63 ```rb
64 subject { CheckingAccount.new }
65 it { is_expected.to be_empty }
66
67 # also names: subject(:account) { ... }
68 ```
69
70 ## Expectations
71
72 ```rb
73 target.should eq 1
74 target.should_not eq 1
75
76 expect(target).to eq 1
77 expect(target).not_to eq 1
78 ```
79
80 ### Numeric
81
82 ```rb
83 expect(5).to be < 6
84 expect(5).to == 5
85 expect(5).to equal value
86 expect(5).to be_between(1, 10)
87 expect(5).to be_within(0.05).of value
88 ```
89
90 ### Compound expectations
91
92 ```rb
93 expect(1).to (be < 2).or be > 5
94 ```
95
96 Use `or`/`and` to string multiple matchers together. See: [Compound expectations](https://relishapp.com/rspec/rspec-expectations/docs/compound-expectations)
97
98 ### Comparison
99
100 ```rb
101 expect(x).to be value
102 expect(x).to satisfy { |arg| ... }
103 expect(x).to match /regexp/
104 ```
105
106 ### Predicate
107
108 ```rb
109 expect(x).to be_zero    # FixNum#zero?
110 expect(x).to be_empty   # Array#empty?
111 expect(x).to have_key   # Hash#has_key?
112 ```
113
114 ### Objects
115
116 ```rb
117 expect(obj).to be_an_instance_of MyClass
118 expect(obj).to be_a_kind_of MyClass
119 expect(obj).to respond_to :save!
120 ```
121
122 ### Control flow
123
124 ```rb
125 expect { user.save! }.to raise_error
126 expect { user.save! }.to raise_error(ExceptionName, /msg/)
127 expect { user.save! }.to throw :symbol
128 ```
129
130 ### Enumerables/arrays
131
132 ```rb
133 expect(list).to include(<object>)
134
135 expect(list).to have(1).things
136 expect(list).to have_at_least(2).things
137 expect(list).to have_at_most(3).things
138
139 expect(list).to have(2).errors_on(:field)
140 ```
141
142 ### Change
143
144 ```rb
145 expect { thing.approve! }.to \
146   change(thing, :status)
147   .from(Status::AWAITING_APPROVAL)
148   .to(Status::APPROVED)
149
150 expect { thing.destroy }.to \
151   change(Thing, :count)
152   .by(-1)
153 ```
154
155 ## Doubles
156
157 ```rb
158 book = double('book')
159 book = instance_double('Book', pages: 250)
160 ```
161
162 ### Method stubs
163
164 ```rb
165 allow(die).to receive(:roll)
166 allow(die).to receive(:roll) { 3 }
167 allow_any_instance_of(Die).to receive(:roll)
168
169 expect(die).to receive(:roll)
170   .with(1)
171   .with(1, true)
172   .with(boolean)
173   .with(anything)
174   .with(any_args)
175   .with(1, any_args)
176   .with(no_args)
177   .with(hash_including(a: 1))
178   .with(hash_excluding(a: 1))
179   .with(array_including(:a, :b))
180   .with(array_excluding(:a, :b))
181   .with(instance_of(Fixnum))
182   .with(kind_of(Numeric))
183   .with(<matcher>)
184
185   .once
186   .twice
187   .exactly(n).times
188   .at_least(:once)
189   .at_least(:twice)
190   .at_least(n).times
191   .at_most(:once)
192   .at_most(:twice)
193   .at_most(n).times
194 ```
195
196 https://relishapp.com/rspec/rspec-mocks/docs
197
198 ## Spec helpers
199
200 ```rb
201 module UserSpecHelper
202   def valid_user_attributes
203     { :email => "joe@bloggs.com",
204       :username => "joebloggs",
205       :password => "abcdefg"}
206   end
207 end
208 ```
209
210 ```rb
211 describe User do
212   include UserSpecHelper
213
214   ...
215 end
216 ```