我收到NoMethodError 对于我的代码,但我已经定义了它说缺少的add方法。 我正在尝试将项添加到已存在的哈希。 哈希是菜肴,我正在尝试使用add方法。
测试:
require 'menu'
describe Menu do
it 'has a menu' do
expect(subject.respond_to?(:dishes)).to be true
end
it 'displays dishes and prices' do
expect(subject.dishes).to eq [
{ name: 'Burger', price: 10.95 },
{ name: 'Pizza', price: 14.00 },
{ name: 'Salad', price: 7.60 },
{ name: 'fries', price: 2.90 }
]
end
it 'can add dishes to it' do
menu = Menu.new
menu.add_dish("Icecream", 4.80)
expect(subject.dishes).to eq [
{ name: 'Burger', price: 10.95 },
{ name: 'Pizza', price: 14.00 },
{ name: 'Salad', price: 7.60 },
{ name: 'fries', price: 2.90 },
{ name: 'icecream', price: 4.80 }
]
end
end
方法
class Menu
def initialize
@dishes = []
end
def dishes
@dishes = [
{ name: 'Burger', price: 10.95 },
{ name: 'Pizza', price: 14.00 },
{ name: 'Salad', price: 7.60 },
{ name: 'fries', price: 2.90 }
]
end
def add_dish(name, price)
@dishes << { name: name, price: price }
end
end
谢谢
答案 0 :(得分:1)
啊,我看到了你的问题。您需要初始化菜单。 Add
不是静态方法。所以你需要类似的东西,
Menu.new.add(blah, blah)
看看:
Menu.add("Icecream", 4.80)
这种方法错了。它必须是:
Menu.new.add("Icecream", 4.80)
或者你需要类似的东西:
menu = Menu.new
menu.add("Icecream", 4.80)
答案 1 :(得分:1)
Ryan-Neal Mes的答案解决了NoMethodError,但您的代码中还有许多其他问题。
你重复自己,你应该让你的代码变干(不要重复自己的原则)
虽然你想在菜单列表中添加一个哈希值,它自己是一个哈希列表,你强制需要调用add方法的对象以特定的顺序提供参数,而不是方法构造哈希,所以每次你需要调用它时,你需要返回它来查看参数的顺序。
dishes
方法错误,因为每次调用它时,它都会将初始数组分配给@dishes
变量。在这种情况下,add_dishes
方法将无效,因为下次调用dishes
方法时将删除添加的菜肴。 这里的测试例子
require 'menu'
describe Menu do
# every time you call the function dishes in an example
# it will be declared and it will return this array
let :dishes do
[
{ name: 'Burger', price: 10.95 },
{ name: 'Pizza', price: 14.00 },
{ name: 'Salad', price: 7.60 },
{ name: 'fries', price: 2.90 }
]
end
# explicit definition of the subject
subject { Menu.new }
# a shorter yet more expressive version of
# expect(subject.respond_to?(:dishes)).to be true
it { is_expected.to respond_to(:dishes) }
# You should always group the examples that test
# the same method
describe '#dishes' do
# it 'displays dishes and prices' do
it 'returns the list of dishes' do
expect(subject.dishes).to eq dishes
end
end
describe "#add_dish" do
# it 'can add dishes to it' do
it "adds the given dish to the list of dishes" do
new_dish = {name: 'salad', price: 4.0 }
expect {
subject.add_dish(new_dish)
}.to change(subject.dishes, :count).by(1)
expect(subject.dishes).to include new_dish
end
end
end
所以这里是类定义
class Menu
# you don't need to declare the method dishes
# since this is what attr_reader will do
attr_reader :dishes
def initialize
# this will set the @dishes only once
# but you code @dishes = [...] will return
# the same list every time you call it and
# all the dishes you add through the #add method
# will be deleted.
@dishes = [
{ name: 'Burger', price: 10.95 },
{ name: 'Pizza', price: 14.00 },
{ name: 'Salad', price: 7.60 },
{ name: 'fries', price: 2.90 }
]
end
# dish is a hash {name: '', price: ''}
def add_dish(dish)
@dishes << dish
end
end
所以现在运行rspec --format doc --color
并查看消息的表达方式。