【问题标题】:How can I return values with an RSpec class_double and as_stubbed_const?如何使用 RSpec class_double 和 as_stubbed_const 返回值?
【发布时间】:2021-02-21 21:46:59
【问题描述】:

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

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

我想存根整个MyVoucherClass 以及它的类方法返回的值。从 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]

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

我正在使用多个 allow(MyVoucherClass) ... and_return() 语句来解决这个问题,但我想知道为什么类 double 和 as_stubbed_const 不起作用,因为最好在一个 class_double 而不是 allow 中执行两次。

【问题讨论】:

    标签: ruby-on-rails ruby rspec mocking


    【解决方案1】:

    let & let!

    注意 let 是惰性求值的:直到第一次才求值 它定义的方法被调用。你可以使用让!强制方法的 在每个示例之前调用。

    您可以在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
    

    【讨论】:

    • 开枪,就这么简单!谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多