简体   繁体   English

如何在Ruby中删除整个数组并使用RSpec进行测试

[英]How to delete an entire array in Ruby and test with RSpec

I'm fairly new to Ruby and am currently taking a full stack course. 我是Ruby的新手,目前正在学习全栈课程。 For one of my projects we are building an addressbook. 对于我的一个项目,我们正在构建一个通讯录。 I have set up how to add an entry to the addressbook, however, I can't seem to figure out how to delete an entry (I make an attempt with the remove_entry method in the AddressBook class below but am not having any luck). 我已经设置了如何向地址簿添加条目,但是,我似乎无法弄清楚如何删除条目(我尝试使用下面的AddressBook类中的remove_entry方法,但是没有任何运气)。 We are also supposed to test first with RSpec, have the test fail and then write some code to get it to pass. 我们还应该首先使用RSpec进行测试,使测试失败,然后编写一些代码以使其通过。 If I didn't include all the info needed for this question let me know (rookie here). 如果我没有提供此问题所需的所有信息,请告诉我(此处是新手)。 Anyway, here is what I have so far: 无论如何,这是我到目前为止所拥有的:

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

AddressBook 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

Entry 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

When testing my code with RSpec I receive the following error message: 使用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

I think your expect has an issue. 我认为您的期望有问题。 The entry variable is not set to nil , but the entry inside book would be nil . entry变量未设置为nil ,但book内部的条目将为nil

I think something like this would work better: 我认为这样会更好:

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

Better still, your AddressBook could have its own find method, which would make the expect param much nicer, like book.find(:name => "Ada Lovelace") . 更好的是,您的AddressBook可以拥有自己的find方法,这将使expect参数更好,例如book.find(:name => "Ada Lovelace")

Finally, I would also put an expect call before the remove_entry call, to make sure its result equals entry . 最后,我还要将期望调用放在remove_entry调用之前 ,以确保其结果等于entry

Just test that the book.entries association is empty: 只需测试book.entries关联为空:

expect(book.entries).to be_empty

As book is a local variable in your test, you will not get a false negative result if you keep your test atomic. 由于book是测试中的局部变量,因此,如果保持测试原子化,就不会得到错误的否定结果。 Some best practices on rspec. 关于rspec的一些最佳实践

Edit : You can also check the entry was not in the set: 编辑 :您还可以检查条目是否不在集合中:

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

or test the change of the array length with: 或使用以下命令测试数组长度的变化:

expect { book.remove_entry(entry) }.to change{book.entries.count}.by(-1)

If you wonder for the be_xxx syntax sugar, if the object respond to xxx? 如果您想知道be_xxx语法糖,那么对象是否响应xxx? , then you can use be_xxx in your tests ( predicate matchers ) ,则可以在测试中使用be_xxx谓词匹配器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM