如何进行绿色的Rspec测试?

时间:2013-12-06 03:08:42

标签: ruby csv rspec tdd automated-tests

下面有一段代码,作为参数从CSV文件中的行中获取信息并创建一个Employee对象。我是Rspec的新手,虽然我知道我的解决方案按照我想要的方式运行,但似乎无法通过我的测试。在学习测试驱动开发的过程中,我想更好地理解Rspec。如何编写显示此代码有效的测试?我意识到这个过程应该反过来(在创建最终产品之前首先测试),但我这样做是为了尝试学习spec如何更好地工作。如果您需要我的更多代码,请告诉我们:

CSV文件:

first_name,last_name,annual_income,tax_paid,tax_rate
Johnny,Smith,120000,28000,38
Jane,Doe,140000,30000,40
Liz,Lemon,,21000,30
,Orsillio,40000,8800,18
Eric,Schmidt,54000,,28

员工类:

class Employee
  attr_reader :last_name, :first_name, :annual_income, :tax_paid, :tax_rate

  def initialize(attributes) **#<-where the csv row is being passed in but in another main file used to run the code**

    @last_name = attributes['last_name'] ||="[Last Name]"
    @first_name = attributes['first_name'] ||="[First Name]"
    @annual_income = attributes['annual_income'].to_f ||= 0
    @tax_paid = attributes['tax_paid'].to_f ||= 0
    @tax_rate = attributes['tax_rate'].to_f ||= 0
  end
end

几次Rspec测试尝试之一:

require 'rspec'
require_relative 'employee'

  describe Employee do
    it 'instantiated Employee class object should instantiate when missing arguments are passed in' do
      expect(Employee.new("").first_name).to eql("[First Name]")
    end
  end

这是测试的结果输出:

F

Failures:

  1) Employee instantiated Employee class object should instantiate when missing arguments are passed in
     Failure/Error: expect(Employee.new("").first_name).to eql("[First Name]")
     IndexError:
       string not matched
     # ./employee.rb:9:in `[]='
     # ./employee.rb:9:in `initialize'
     # ./employee_spec.rb:6:in `new'
     # ./employee_spec.rb:6:in `block (2 levels) in <top (required)>'

Finished in 0.00029 seconds
1 example, 1 failure

Failed examples:

rspec ./employee_spec.rb:5 # Employee instantiated Em

1 个答案:

答案 0 :(得分:0)

这不是您的测试错误,而是您的测试非常好地告诉您,您的代码存在问题。

你有

@last_name = attributes['last_name'] ||="[Last Name]"

也许您应该在尝试分配之前检查属性参数是否包含您要查找的值?所有属性都是一样的

错误很可能是因为您正在将一个字符串作为参数传递而不是散列,但是当您调用Employee.new("")

时,您正试图访问该字符串,就好像它是一个哈希值一样

所以将初始化方法更改为此

  def initialize(attributes) #**#<-where the csv row is being passed in but in another main file used to run the code**
    if attributes.is_a? Hash
        @last_name = attributes['last_name'] ||="[Last Name]"
        @first_name = attributes['first_name'] ||="[First Name]"
        @annual_income = attributes['annual_income'].to_f ||= 0
        @tax_paid = attributes['tax_paid'].to_f ||= 0
        @tax_rate = attributes['tax_rate'].to_f ||= 0
    else
        @last_name = "[Last Name]"
        @first_name = "[First Name]"
        @annual_income = 0
        @tax_paid =  0
        @tax_rate =  0
    end
  end

您的考试将通过,您的课程已修复。

测试摇滚! :)