我正在学习 rspec 并且我已经编写了规范但它部分失败了

I am learning rspec and I have written a spec but it fails partially

我想要一种检查方法是否引发错误的方法

我试过以下方法:

expect(described_class.new.convert_to_pdf).to raise_error

class Invoice
    def self.convert_to_pdf
        "Yay"
    end
end

RSpec.describe Invoice do
    describe '#convert_to_pdf' do
        it "Should work" do 
            expect(described_class.convert_to_pdf).to eql("Yay")
        end

        it "should not work on object" do 
            expect(described_class.new.convert_to_pdf).to raise_error
        end
    end
end

我希望两个测试都通过,因为我想向我的同事解释 class 方法和实例方法有何不同

请参考我的错误:

1) 发票#convert_to_pdf 不应在对象上工作 Failure/Error: (described_class.new.convert_to_pdf).应该raise_error

 NoMethodError:
   undefined method `convert_to_pdf' for #<Invoice:0x007fa48e2b2ac0>
 # ./methods.rb:91:in `block (3 levels) in <top (required)>'

这很微妙,但是有两种定义 expect 定义的方法。第一个是你提供 a valueexpression:

expect(x).to be_something

此处立即计算表达式,然后expect才有机会做它的事情。

实际上您的代码如下所示:

x = described_class.new.convert_to_pdf # Exception happens here
expect(x).to raise_error # Too late, already popped an exception

第二种形式是你提供一个块:

expect { x }.to raise_error

这里的块 expect 本身评估 并且它能够捕获和检查生成的任何错误。

当使用 raise_error 时,您需要块形式,否则异常会通过 expect 的救援机制。

您可以使用 respond_to 来测试方法是否在 class and/or 实例上定义:

RSpec.describe Invoice do
  describe '#convert_to_pdf' do
    it "should work on class" do 
      expect(described_class).to respond_to(:convert_to_pdf)
    end

    it "should not work on instance" do 
      expect(described_class.new).to_not respond_to(:convert_to_pdf)
    end
  end
end

这样:

  • 不会出现错误
  • 两个测试都会通过,并且
  • 你可以解释一下定义方法的位置。

注意:它不测试方法的return值。

希望对您有所帮助。