RSpec - how to fix - ArgumentError: wrong number of arguments (given 0, expected 1) - Ruby
RSpec - how to fix - ArgumentError: wrong number of arguments (given 0, expected 1) - Ruby
我刚开始学习 RSpec。我似乎无法理解为什么我的测试 #start method
失败了。
如果有人能向我解释一下,将不胜感激。
我遇到的错误:
CardGame
attributes
should have a name
#response method
should say hello
#start method
can only implement class methods that are defined on a class (FAILED - 1)
Failures:
1) CardGame#start method can only implement class methods that are defined on a class
Failure/Error:
def initialize(name)
@name = name
end
ArgumentError:
wrong number of arguments (given 0, expected 1)
# ./lib/CardGame.rb:4:in `initialize'
# ./spec/class_double_spec.rb:29:in `block (3 levels) in <top (required)>'
Finished in 0.01178 seconds (files took 0.30252 seconds to load)
3 examples, 1 failure
Failed examples:
rspec ./spec/class_double_spec.rb:27 # CardGame#start method can only implement class methods that are defined on a class
➜ rspec-course
class_double_spec.rb
[ruby/spec/class_double_spec.rb]
require 'spec_helper'
require 'pry'
require './lib/CardGame'
require './lib/Deck'
describe CardGame do
let(:card) { instance_double(CardGame,
name: 'poker',
response: 'hello')}
let(:deck_klass) { class_double(Deck, build: ['Ace', 'Queen']).as_stubbed_const }
context 'attributes' do
it 'should have a name' do
expect(card.name).to eq('poker')
end
end
context '#response method' do
it 'should say hello' do
allow(card).to receive(:response).and_return('hello')
expect(card.response).to eq('hello')
end
end
context '#start method' do
it 'can only implement class methods that are defined on a class' do
expect(deck_klass).to receive(:build)
card.start
expect(card.cards).to eq(['Ace', 'Queen'])
end
end
end
CardGame.rb
[ruby/lib/CardGame.rb]
class CardGame
attr_accessor :name, :cards
def initialize(name)
@name = name
end
def response
'hello'
end
def start
@cards = Deck.build
end
end
Deck.rb
[ruby/lib/Deck.rb]
class Deck
def self.build
# business logic to build cards
end
end
你嘲笑嘲笑。应该严格应用的规则之一是不要模拟被测单元,所以
describe CardGame do
let(:card) { instance_double(CardGame,
name: 'poker',
response: 'hello')}
let(:deck_klass) { class_double(Deck, build: ['Ace', 'Queen']).as_stubbed_const }
context 'attributes' do
it 'should have a name' do
expect(card.name).to eq('poker')
end
end
end
这样做
describe CardGame do
let(:card) { CardGame.new(name) }
let(:name) { 'poker'}
context 'attributes' do
it 'should have a name' do
expect(card.name).to eq('poker')
end
end
end
为什么不模拟被测单元?
context '#response method' do
it 'should say hello' do
allow(card).to receive(:response).and_return('hello')
expect(card.response).to eq('hello')
end
end
因为在示例中,您只是在测试 RSpec 的模拟框架是否有效。简化它
context '#response method' do
it 'should say hello' do
expect(card.response).to eq('hello')
end
end
最后一个例子:
context '#start method' do
it 'can only implement class methods that are defined on a class' do
expect(deck_klass).to receive(:build)
card.start
expect(card.cards).to eq(['Ace', 'Queen'])
end
end
看起来更好,模拟的class没有直接测试,而是被测试单元(Card
)使用。
如果您正在学习 RSpec - 尽量少模拟。这将迫使您设计 classes 以便于测试。现在您正在以旧的习惯性方式设计它,这使得 class 难以测试,这迫使您使用模拟(并且由于您只是在学习 - 很容易在您没有的地方发现 placec '测试任何东西)
我刚开始学习 RSpec。我似乎无法理解为什么我的测试 #start method
失败了。
如果有人能向我解释一下,将不胜感激。
我遇到的错误:
CardGame
attributes
should have a name
#response method
should say hello
#start method
can only implement class methods that are defined on a class (FAILED - 1)
Failures:
1) CardGame#start method can only implement class methods that are defined on a class
Failure/Error:
def initialize(name)
@name = name
end
ArgumentError:
wrong number of arguments (given 0, expected 1)
# ./lib/CardGame.rb:4:in `initialize'
# ./spec/class_double_spec.rb:29:in `block (3 levels) in <top (required)>'
Finished in 0.01178 seconds (files took 0.30252 seconds to load)
3 examples, 1 failure
Failed examples:
rspec ./spec/class_double_spec.rb:27 # CardGame#start method can only implement class methods that are defined on a class
➜ rspec-course
class_double_spec.rb
[ruby/spec/class_double_spec.rb]
require 'spec_helper'
require 'pry'
require './lib/CardGame'
require './lib/Deck'
describe CardGame do
let(:card) { instance_double(CardGame,
name: 'poker',
response: 'hello')}
let(:deck_klass) { class_double(Deck, build: ['Ace', 'Queen']).as_stubbed_const }
context 'attributes' do
it 'should have a name' do
expect(card.name).to eq('poker')
end
end
context '#response method' do
it 'should say hello' do
allow(card).to receive(:response).and_return('hello')
expect(card.response).to eq('hello')
end
end
context '#start method' do
it 'can only implement class methods that are defined on a class' do
expect(deck_klass).to receive(:build)
card.start
expect(card.cards).to eq(['Ace', 'Queen'])
end
end
end
CardGame.rb
[ruby/lib/CardGame.rb]
class CardGame
attr_accessor :name, :cards
def initialize(name)
@name = name
end
def response
'hello'
end
def start
@cards = Deck.build
end
end
Deck.rb
[ruby/lib/Deck.rb]
class Deck
def self.build
# business logic to build cards
end
end
你嘲笑嘲笑。应该严格应用的规则之一是不要模拟被测单元,所以
describe CardGame do
let(:card) { instance_double(CardGame,
name: 'poker',
response: 'hello')}
let(:deck_klass) { class_double(Deck, build: ['Ace', 'Queen']).as_stubbed_const }
context 'attributes' do
it 'should have a name' do
expect(card.name).to eq('poker')
end
end
end
这样做
describe CardGame do
let(:card) { CardGame.new(name) }
let(:name) { 'poker'}
context 'attributes' do
it 'should have a name' do
expect(card.name).to eq('poker')
end
end
end
为什么不模拟被测单元?
context '#response method' do
it 'should say hello' do
allow(card).to receive(:response).and_return('hello')
expect(card.response).to eq('hello')
end
end
因为在示例中,您只是在测试 RSpec 的模拟框架是否有效。简化它
context '#response method' do
it 'should say hello' do
expect(card.response).to eq('hello')
end
end
最后一个例子:
context '#start method' do
it 'can only implement class methods that are defined on a class' do
expect(deck_klass).to receive(:build)
card.start
expect(card.cards).to eq(['Ace', 'Queen'])
end
end
看起来更好,模拟的class没有直接测试,而是被测试单元(Card
)使用。
如果您正在学习 RSpec - 尽量少模拟。这将迫使您设计 classes 以便于测试。现在您正在以旧的习惯性方式设计它,这使得 class 难以测试,这迫使您使用模拟(并且由于您只是在学习 - 很容易在您没有的地方发现 placec '测试任何东西)