首页 > 解决方案 > Rspec - 使用模拟回溯创建 StandardError 实例

问题描述

如何在 rspec 中创建一个包含回溯字符串数组的错误实例?

我试过了

let(:mocked_error) { StandardError.new('Mocked Standard Error') }

这会产生错误,但如何添加回溯?

理想情况下,我当然想要类似但不是哈希的东西

{ :message => 'mocked error', :backtrace => ['bla', 'bla2'] }

标签: rubyrspecrspec-rails

解决方案


有可能的:

  specify do
    mock = Class.new(StandardError) do
      def backtrace
        ["foo", "bar"]
      end
    end

    def dostuff(exception)
      raise exception
    rescue => e
      e.backtrace
    end

    expect(dostuff(mock)).to eq(["foo", "bar"])
  end

只需以一种可以提供要抛出的异常类的方式组织代码,就可以了。

但是问题来了:你应该这样做吗?

您似乎计划根据回溯中的内容更改代码行为。我建议您针对您尝试使用回溯解决的问题添加一个新问题,也许有人可以提出另一种方法。


以下是旧版本的答案,我认为通过允许我找到解决方案的测试是不可能的

如果您想提出这样的例外,我认为这是不可能的。

看看我做的小测试:

  specify do
    mock = instance_double(StandardError, backtrace: ["foo", "bar"])

    expect(mock.backtrace).to eq(["foo", "bar"]) # pass

    def dostuff(exception)
      raise exception
    rescue => e
      return e.backtrace
    end

    expect(dostuff(mock)).to eq(["foo", "bar"]) #fails
  end

失败是:

       expected: ["foo", "bar"]
            got: [real_backtrace_here]

为什么?考虑相同的测试,改变一个但是(返回捕获的异常而不是回溯):

  specify do
    mock = instance_double(StandardError, backtrace: ["foo", "bar"])

    def dostuff(exception)
      raise exception
    rescue => e
      e
    end

    expect(dostuff(mock)).to eq(mock)
  end

现在的失败消息:

       expected: #<InstanceDouble(StandardError) (anonymous)>
            got: #<TypeError: exception class/object expected>

似乎抛出或捕获异常会导致创建新的异常对象。(不正确,见下文)

您似乎计划根据回溯中的内容更改代码行为。我建议您针对您尝试使用回溯解决的问题添加一个新问题,也许有人可以提出另一种方法。

编辑:我刚刚意识到:

       -#<InstanceDouble(StandardError) (anonymous)>
       +#<TypeError: exception class/object expected>

这不是重新创建的异常,这是我尝试引发模拟时引发的新异常,而 ruby​​ 不允许这样做。


推荐阅读