如何使用 RSpec class_double 和 as_stubbed_const 来 return 值?

How can I return values with an RSpec class_double and as_stubbed_const?

我有一个 class MyVoucherClass 在 Rails 应用程序中调用单独的服务。

在我正在测试的 class 中,VoucherIssuer,我正在调用 MyVoucherClass 的两个 class 方法,issue_voucheractivate_voucher 其中 POST 到单独的服务。

我想存根整个 MyVoucherClass 及其 class 方法的值 return。从 RSpec 文档和进一步搜索中,我发现以下内容应该有效:

subject(:issue_credits) { described_class.new.issue_credits }

let(:my_voucher_class_double) do
  class_double(MyVoucherClass,
               issue_voucher: { voucher_id: "ABC123" }.to_json,
               activate_voucher: instance_double(VoucherClass, voucher_id: "ABC123")
  ).as_stubbed_const
end

context “when using MyVoucherClass” do
    it “calls on MyVoucherService” do
        issue_credits
    end
end

但是,它抛出错误:

WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: POST [separate service url]

这意味着 return 值存根方法不起作用。

我正在使用多个 allow(MyVoucherClass) ... and_return() 语句来解决这个问题,但我想知道为什么 class double 和 as_stubbed_const 不起作用,因为这样做是理想的在一次 class_double 而不是 allow 两次。

let & let!

Note that let is lazy-evaluated: it is not evaluated until the first time the method it defines is invoked. You can use let! to force the method's invocation before each example.

您可以在 it 块内调用 my_voucher_class_double 来调用或使用 let! 而不是 let

  • 使用let
   subject(:issue_credits) { described_class.new.issue_credits }

   let(:my_voucher_class_double) do
     class_double(MyVoucherClass,
                  issue_voucher: { voucher_id: "ABC123" }.to_json,
                  activate_voucher: instance_double(VoucherClass, voucher_id: "ABC123")
     ).as_stubbed_const
   end

   context “when using MyVoucherClass” do
       it “calls on MyVoucherService” do
           my_voucher_class_double
           issue_credits
       end
   end
  • 使用let!
   subject(:issue_credits) { described_class.new.issue_credits }

   let!(:my_voucher_class_double) do
     class_double(MyVoucherClass,
                  issue_voucher: { voucher_id: "ABC123" }.to_json,
                  activate_voucher: instance_double(VoucherClass, voucher_id: "ABC123")
     ).as_stubbed_const
   end

   context “when using MyVoucherClass” do
       it “calls on MyVoucherService” do
           issue_credits
       end
   end