用于访问RSpec中主题层次结构的模式

Sim*_*Sim 10 automated-tests unit-testing rspec ruby-on-rails rspec2

当使用RSpec测试深层嵌套的数据结构时,我发现需要根据包含上下文中的主题在嵌套上下文中定义主题.我已经看了很多,但没有找到任何关于如何处理的例子而没有定义很多变量.它使规范复杂化并限制了规范重用的可能性.我很好奇是否有办法在RSpec中做到这一点,如果没有,那么什么是解决问题的好方法.

现在,我的代码看起来像:

context 'with a result which is a Hash' do
  before do
    @result = get_result()
  end
  subject { @result }
  it { should be_a Hash }
  context 'with an Array' do
    before do
      @array_elem = @result[special_key]
    end
    subject { @array_elem }
    it { should be_an Array }
    context 'that contains a Hash' do
      before do
        @nested_hash = ...
      end
      subject { @nested_hash }
      ...
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

相反,我宁愿写下以下内容:

context 'with a result which is a Hash' do
  subject { get_result }
  it { should be_a Hash }
  context 'with an Array' do
    subject { parent_subject[special_key] }
    it { should be_an Array }
    context 'that contains a Hash' do
      subject { do_something_with(parent_subject) }
      ...
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

使用这种类型的自动主题层次结构管理扩展RSpec的方法是什么?

She*_*aun 10

我正在寻找同样的东西,并希望使用,subject以便我可以使用its,所以我实现它像这样:

describe "#results" do
  let(:results) { Class.results }

  context "at the top level" do
    subject { results }

    it { should be_a Hash }
    its(['featuredDate']) { should == expected_date }
    its(['childItems']) { should be_a Array }
  end

  context "the first child item" do
    subject { results['childItems'][0] }

    it { should be_a Hash }
    its(['title']) { should == 'Title' }
    its(['body']) { should == 'Body' }
  end

  context "the programme info for the first child item" do
    subject { results['childItems'][0]['programme'] }

    it { should be_a Hash }
    its(['title']) { should == 'title' }
    its(['description']) { should == 'description' }
  end
end
Run Code Online (Sandbox Code Playgroud)


小智 6

我在尝试做类似的事情时发现了这个问题.我的解决方案可以在https://gist.github.com/asmand/d1ccbcd01789353c01c3找到

它的作用是测试圣诞节一周的弹性工作时间计算,即给定周,只有周一和周五是工作日,其余是假期.

解决方案基于命名主题.即

describe WeeklyFlexCalculator, "during Christmas week" do

  subject(:calculation) { WeeklyFlexCalculator.new(params).calculate }

  context "with no work performed" do
    it { should have(1).item }

    context "the week calculated" do
      subject(:workweek) {calculation[0]}

      its([:weekTarget]) { should eq 15.0 }
      its([:weekEffort]) { should eq 0.0 }

      context "the work efforts" do
        subject(:efforts) {workweek[:efforts]}

        it { should have(2).items }

        context "the first work effort" do
          subject(:effort) {efforts[0]}

          its([:target]) {should eq 7.5}
          its([:diff]) {should eq -7.5}
          its([:effort]) {should eq 0.0}
        end
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

为简洁起见,省略了许多代码,但完整的示例可以在链接的要点中找到.


nat*_*vda 2

在这种类型的层次结构中,我实际上会放弃使用subject并使主题变得明确。虽然这可能会导致更多的输入(如果您有很多测试),但它也更清晰。如果您向下三个级别,嵌套subject语句也可能会混淆实际测试的内容。

  context 'with a result which is a Hash' do
    before do
      @result = get_result()
    end
    it { @result.should be_a Hash }
    context 'special_key' do
      before do
        @array_elem = @result[special_key]
      end
      it { @array_elem.should be_an Array }
      context 'that contains a Hash' do
        before do
          @nested_hash = ...
        end
        it { @nested_hash.should be_a Hash }
        ...
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

但这可能是一个品味问题。希望这可以帮助。

  • 或使用命名主题,如“subject(:name) { @result[special_key] }” (2认同)