2015-06-19 38 views
0

我对Ruby相当陌生,目前正在完成一个完整的堆栈课程。对于我的一个项目,我们正在建立一个地址簿。我已经设置了如何添加一个条目到地址簿,但是,我似乎无法弄清楚如何删除一个条目(我尝试使用AddressBook类中的remove_entry方法,但没有任何运气)。我们也应该首先测试RSpec,让测试失败,然后编写一些代码让它通过。如果我没有包含这个问题所需的所有信息,请让我知道(菜鸟在这里)。总之,这里是我到目前为止有:如何在Ruby中删除整个数组并使用RSpec进行测试

RSpec的

context ".remove_entry" do 
    it "removes only one entry from the address book" do 
     book = AddressBook.new 
     entry = book.add_entry('Ada Lovelace', '010.012.1815', '[email protected]') 
     book.remove_entry(entry) 

     expect(entry).to eq nil 
    end 
    end 

AddressBook类

require_relative "entry.rb" 

class AddressBook 
    attr_accessor :entries 

    def initialize 
    @entries = [] 
    end 

    def add_entry(name, phone, email) 
    index = 0 
    @entries.each do |entry| 
     if name < entry.name 
     break 
     end 
     index += 1 
    end 

    @entries.insert(index, Entry.new(name, phone, email)) 
    end 

    def remove_entry(entry) 
    @entries.delete(entry) 
    end 
end 

Entry类

class Entry 
    attr_accessor :name, :phone_number, :email 

    def initialize(name, phone_number, email) 
    @name = name 
    @phone_number = phone_number 
    @email = email 
    end 

    def to_s 
    "Name: #{@name}\nPhone Number: #{@phone_number}\nEmail: #{@email}" 
    end 
end 

当与RSpec的测试我的代码,我收到以下错误消息:

.....F 

Failures: 

    1) AddressBook.remove_entry removes only one entry from the address book 
    Failure/Error: expect(entry).to eq nil 

     expected: nil 
      got: [#<Entry:0x00000101bc82f0 @name="Ada Lovelace", @phone_number="010.012.1815", @email="[email protected]">] 

     (compared using ==) 
    # ./spec/address_book_spec.rb:49:in `block (3 levels) in <top (required)>' 

Finished in 0.02075 seconds (files took 0.14221 seconds to load) 
6 examples, 1 failure 

Failed examples: 

rspec ./spec/address_book_spec.rb:44 # AddressBook.remove_entry removes only one entry from the address book 

回答

1

只是测试了book.entries协会是空的:

expect(book.entries).to be_empty 

由于本书是在测试一个局部变量,如果你把你的测试原子,你不会得到假阴性结果。 rspec上的一些best practices

编辑: 您还可以检查该条目不在集合:

expect(book.entries.index(entry)).to be_nil 

或测试数组长度与变化:如果你想知道的

​​

be_xxx语法糖,如果对象响应xxx?,那么您可以在您的测试中使用be_xxxpredicate matchers

+0

在这种情况下,我不认为'entry'或'book'有'reload'方法。然而'be_empty'的期望很好。我唯一的缺点是,如果测试增长或被重复使用,如果之前添加了其他一些条目,可能会产生误报。 – lilole

+0

你是对的!我一直在寻找ruby-on-rails问题,但这是纯粹的ruby。我会更新答案。如果你保持原子的测试,你就不会有这个问题。 'book'是在'it'内部创建的局部变量,那么它就不会与其他测试产生冲突。 –

+0

谢谢!现在对我有意义! – jlquaccia

1

我认为你的期望有问题。 entry变量未设置为nil,但条目book将为nil

我觉得这样的事情会更好地工作:

expect(book.entries.find { |e| e.name == "Ada Lovelace" }).to eq nil 

更妙的是,你的AddressBook可以有自己的find方法,这将使expect PARAM好得多,像book.find(:name => "Ada Lovelace")

最后,我还会在之前拨打的电话,以确保其结果等于entry