【问题标题】:DRY double in RSpecRSpec 中的 DRY 双倍
【发布时间】:2019-01-08 14:12:28
【问题描述】:

如何干燥(不要重复自己)RSpec 中的双重?例如:

let(:s1) {instance_double(Class1,
                            :attr1 => val1,
                            :attr2 => val2,
                            :attr3 => val3,
                            :attr4 => val4,
                            :attr5 => val5)}


let(:s2) {instance_double(Class1,
                            :attr1 => val0, # the only difference between s2 and s1
                            :attr2 => val2,
                            :attr3 => val3,
                            :attr4 => val4,
                            :attr5 => val5)}

let(:s3) {instance_double(Class1,
                            :attr1 => val6, # the only difference between s3 and s1
                            :attr2 => val2,
                            :attr3 => val3,
                            :attr4 => val4,
                            :attr5 => val5)}

这 3 个 double 非常相似,似乎我们可以重构。但我试过了:

  1. 为他们做一个基本的哈希:

    basic_hash = {attr2 => val2, attr3 => val3, attr4 => val4, attr5 => val5}

然后修改这个基础hash,传入instance_double,比如传入:s1

basic_hash_s1 = basic_hash.clone
basic_hash_s1[:attr1] = val1
let(:s3) {instance_double(Class1, basic_hash_s1)

但这不起作用。我正在处理一个现有项目,Rspec 没有给出任何错误消息(也许项目有一些设置?),它只是跳过了整个规范文件。

  1. 我也尝试过允许加倍:

    allow(s1).to receive(:attr).and_return(val1)

还是不行。

有人知道如何重构吗?谢谢!

=======编辑=======

我尝试创建double Hash对象并将其传递给:s1,它可以传递,但我不知道如何修改该double中的内容:我尝试修改它与修改a相同常规的 Hash 对象,但它不起作用。

【问题讨论】:

    标签: ruby testing rspec dry ruby-1.8


    【解决方案1】:

    使用函数

    let(:create_s) do
        -> |attr1| do
             instance_double(Class1,
                            :attr1 => attr1
                            :attr2 => val2
                            :attr3 => val3
                            :attr4 => val4
                            :attr5 => val5)
        end
    end
    
    let(:s1) { create_s.call(val1) }
    let(:s2) { create_s.call(val0) }
    let(:s3) { create_s.call(val6) }
    

    【讨论】:

    • 为什么不使用常规方法? def create_s(attr1); instance_double(...
    • 因为您可以根据需要在不同的上下文中覆盖let。如果没有,那么方法也会起作用
    • 你也可以重写方法,仅供参考
    • @matthewd:如果嵌套上下文是外部上下文的后代,那就可以了。我怀疑这的情况,但现在无法检查。
    【解决方案2】:
    let(:opts) { { :attr1 => val1,
                  :attr2 => val2,
                  :attr3 => val3,
                  :attr4 => val4,
                  :attr5 => val5 } }
    
    let(:s1) { instance_double(Class1, opts) }
    let(:s2) { instance_double(Class1, opts.merge(:attr1 => val0)) }
    let(:s3) { instance_double(Class1, opts.merge(:attr1 => val6)) }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2014-02-28
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      相关资源
      最近更新 更多