如何删除 Ruby 中的整个数组并使用 RSpec 进行测试
How to delete an entire array in Ruby and test with RSpec
我是 Ruby 的新手,目前正在学习全栈课程。对于我的一个项目,我们正在构建一个地址簿。我已经设置了如何向地址簿添加条目,但是,我似乎无法弄清楚如何删除条目(我尝试使用下面地址簿 class 中的 remove_entry 方法但我没有任何运气)。我们还应该先用 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', 'augusta.king@lovelace.com')
book.remove_entry(entry)
expect(entry).to eq nil
end
end
地址簿class
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
条目class
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="augusta.king@lovelace.com">]
(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
我认为你的期望有问题。 entry
变量未设置为 nil
,但 book
内的 条目 将是 nil
。
我认为这样的方法会更好:
expect(book.entries.find { |e| e.name == "Ada Lovelace" }).to eq nil
更好的是,您的 AddressBook
可以有自己的 find
方法,这将使 expect
参数更好,例如 book.find(:name => "Ada Lovelace")
.
最后,我还会在 remove_entry
调用 之前放置一个 expect 调用 ,以确保其结果等于 entry
.
只需测试 book.entries 关联是否为空:
expect(book.entries).to be_empty
由于 book 是测试中的局部变量,如果保持测试的原子性,就不会得到假阴性结果。 rspec.
上的一些 best practices
编辑:
您还可以检查条目不在集合中:
expect(book.entries.index(entry)).to be_nil
或者测试数组长度的变化:
expect { book.remove_entry(entry) }.to change{book.entries.count}.by(-1)
如果您想知道 be_xxx
语法糖,如果对象响应 xxx?
,那么您可以在测试中使用 be_xxx
(predicate matchers)
我是 Ruby 的新手,目前正在学习全栈课程。对于我的一个项目,我们正在构建一个地址簿。我已经设置了如何向地址簿添加条目,但是,我似乎无法弄清楚如何删除条目(我尝试使用下面地址簿 class 中的 remove_entry 方法但我没有任何运气)。我们还应该先用 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', 'augusta.king@lovelace.com')
book.remove_entry(entry)
expect(entry).to eq nil
end
end
地址簿class
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
条目class
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="augusta.king@lovelace.com">]
(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
我认为你的期望有问题。 entry
变量未设置为 nil
,但 book
内的 条目 将是 nil
。
我认为这样的方法会更好:
expect(book.entries.find { |e| e.name == "Ada Lovelace" }).to eq nil
更好的是,您的 AddressBook
可以有自己的 find
方法,这将使 expect
参数更好,例如 book.find(:name => "Ada Lovelace")
.
最后,我还会在 remove_entry
调用 之前放置一个 expect 调用 ,以确保其结果等于 entry
.
只需测试 book.entries 关联是否为空:
expect(book.entries).to be_empty
由于 book 是测试中的局部变量,如果保持测试的原子性,就不会得到假阴性结果。 rspec.
上的一些 best practices编辑: 您还可以检查条目不在集合中:
expect(book.entries.index(entry)).to be_nil
或者测试数组长度的变化:
expect { book.remove_entry(entry) }.to change{book.entries.count}.by(-1)
如果您想知道 be_xxx
语法糖,如果对象响应 xxx?
,那么您可以在测试中使用 be_xxx
(predicate matchers)