我可以在Ruby中存根“加注”吗?

时间:2012-02-07 14:20:13

标签: ruby exception testing exception-handling rspec

我有一个名为RemoteError的课程,上面有self.fatal方法。此方法作业基本上是捕获异常,将异常的详细信息发送到服务器,然后传播异常以杀死程序。

class RemoteError
  def initialize(label, error)
    @label = label
    @error = error
  end

  def self.fatal(label, error)
    object = new(label, error)
    object.send
    raise error
  end

  def send
    # send the error to the server
  end
end

我试图为RemoteError.fatal方法编写测试。这很困难,因为在方法中调用了raise。每次我运行测试时,raise显然会引发异常,我无法测试send被调用。

  describe "fatal" do
    it "should send a remote error" do
      error = stub
      RemoteError.stub(:new) { error }
      error.should_receive(:send)

      RemoteError.fatal(stub, stub)
    end
  end

有没有办法可以存根或以某种方式绕过raise进行此特定测试?

2 个答案:

答案 0 :(得分:9)

你可以在lambda中包装引发错误的方法......

it "should send a remote error" do
  ...

  lambda { RemoteError.fatal(stub, stub) }.should raise_error(error)
end    

这实际上允许调用该方法,并从中获取返回值或引发的错误,然后使用.should raise_error(error)进行断言。这也是因为如果从该调用中引发无错误,则测试将正常失败。

换句话说,你不需要也不想要存根raise。只需将其包装在lambda中,您的代码将继续执行,您应该能够确保您的消息已发送,并且您的测试不会退出/崩溃。

答案 1 :(得分:3)

在测试中,您正在测试引发错误的方法,这是方法执行的预期结果。您应该使用以下语法编写异常期望:

lambda{ RemoteError.fatal(stub, stub) }.should raise_error

在这种情况下,如果不会引发异常,您的规范将失败,如果不满足所有其他期望(如should_receive(:sen)),您的规范也将失败。