我可以在nexted上下文中逐步配置测试主题吗?

时间:2016-01-04 19:52:12

标签: ruby rspec

我是Ruby和RSpec的新手,我正在寻找一种在嵌套上下文中逐步配置测试主题的方法。我想做的事情可以通过以下方式来说明,显然是做作的例子:

describe "Array" do
  context "An array" do
    let (:array_length) do
      a = Array.new
      config_array a
      return a.length
    end

    context "with 1 element" do
      def config_array(arr)
        arr << '1'
      end

      it "should have length 1" do
        expect(array_length).to eq(1) 
      end

      context "and an additional element" do
        def config_array(arr)
          arr << '1'
          arr << '2'
        end

        it "should have length 2" do
          expect(array_length).to eq(2)
        end

        context "and yet another additional element" do
          def config_array(arr)
            arr << '1'
            arr << '2'
            arr << '3'
          end

          it "should have length 3" do
            expect(array_length).to eq(3)       
          end
        end
      end
    end
  end
end

此示例中的测试通过,但我希望能够执行以下操作:

# snip      
      context "and an additional element" do
        def config_array(arr)
          parent_context_config_array arr
          arr << '2'
        end

        it "should have length 2" do
          expect(array_length).to eq(2)
        end

        context "and yet another additional element" do
          def config_array(arr)
            parent_context_config_array arr
            arr << '3'
          end
# snip      

有一种简单的方法吗?显然,我正在使用的真实测试对象比这更复杂。我基本上是在寻找一种方法来保持代码DRY,同时在嵌套的上下文中为测试主题添加额外的配置。

1 个答案:

答案 0 :(得分:1)

我会做那样的事情:

describe 'Array' do
  subject { Array.new }

  context '#length' do
    context 'with 1 element' do
      before { subject << '1' }

      it 'should eq 1' do
        expect(subject.length).to eq 1
      end

      context 'and an additional element' do
        before { subject << '2' }

        it 'should eq 2' do
          expect(subject.length).to eq 2 
        end

        # ...
      end
    end
  end
end

给定 it 块的父上下文中的所有之前块(之前(:每个)的快捷方式)将是在实际的 it 代码之前按降序进行评估。这就形成了我们所谓的榜样。

主题方法只是围绕 let 方法的语法糖。我们第一次在示例中调用它时,我们在 subject 声明中提供的块被评估并且其结果被记忆。因此,在该特定示例中对主题的任何不可告人的调用将返回相同的对象。 我们在第二个例子中利用了这个,两个元素的一个。第一个之前调用主题来评估 Array.new 会返回数组并记住它。然后,&lt;&lt; 方法修改现在已记住的对象,该对象将在第二个之前块中再次修改,以便在达到预期时确实包含两个元件。