rspec 测试书写规范

之前很为写测试头痛,从现在开始测试也要认真写啊 😂 。
总是搞不懂 describe context it let subject before/after 之间先后顺序以及含义。大概看了一个 rspec-style-guide,可以有一定的了解。本文摘自 The RSpec Style Guide,详尽的请参考原文。

完整结构:

class

1
2
3
4
5
6
7
8
9
class Article
def summary
#...
end
def self.latest
#...
end
end

article_spec.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
describe Article do
subject { FactoryGirl.create(:some_article) }
let(:user) { FactoryGirl.create(:user) }
before do
# ...
end
after do
# ...
end
describe '#summary' do
context 'when there is a summary' do
it 'returns the summary' do
# ...
end
end
end
describe '.latest' do
context 'when latest' do
it 'returns the latest data' do
# ...
end
end
end
end

articles_controller_spec.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# A classic example for use of contexts in a controller spec is creation or update when the object saves successfully or not.
describe ArticlesController do
let(:article) { double(Article) }
describe 'POST create' do
before { allow(Article).to receive(:new).and_return(article) }
it 'creates a new article with the given attributes' do
expect(Article).to receive(:new).with(title: 'The New Article Title').and_return(article)
post :create, article: { title: 'The New Article Title' }
end
it 'saves the article' do
expect(article).to receive(:save)
post :create
end
context 'when the article saves successfully' do
before do
allow(article).to receive(:save).and_return(true)
end
it 'sets a flash[:notice] message' do
post :create
expect(flash[:notice]).to eq('The article was saved successfully.')
end
it 'redirects to the Articles index' do
post :create
expect(response).to redirect_to(action: 'index')
end
end
context 'when the article fails to save' do
before do
allow(article).to receive(:save).and_return(false)
end
it 'assigns @article' do
post :create
expect(assigns[:article]).to eq(article)
end
it 're-renders the 'new' template' do
post :create
expect(response).to render_template('new')
end
end
end
end