RSpec

时间:2015-04-26 03:34:49

标签: ruby rspec

我试图使用RSpec进入BDD,并且我很难通过简单的示例来缩放技术。

http://betterspecs.org/#contexts通知我,我应该使用'上下文'方法让我的期望更容易描述。我有两个问题:

1)在'环境中包装测试'创建一个新的范围,所以我的设置必须多次完成。我还没有找到一种方法来使用'之前'挂钩使这个干 - 你可以看到下面重复的代码。

2)您在下面看到的案例是一个循序渐进的过程,因此每个步骤都会构建下一个步骤。首先实例化Compositor,然后添加一条指令,然后清除指令。如果1)得到解决,这不是一个很大的技术问题,但是你会注意到上下文描述开始滚雪球,这似乎打败了上下文的目的'方法

有人建议使用重构来使这组测试符合最佳实践吗?

require 'spec_helper'

describe Compositor do

  context 'when instantiated with correct parameters' do
    renderer = USBTeensyRenderer.new("/dev/tty.usbmodem54121", 9600)
    comp = Compositor.new(renderer, [0, 0, 255, 255])
    it 'has a bounding rectangle' do
      expect(comp.bounding_box).to eq([0, 0, 255, 255])
    end
    it 'has a renderer' do
      expect(comp.renderer).to eq(renderer)
    end
    it 'has an empty array of drawing instructions' do
      expect(comp.drawing_instructions).to eq([])
    end
  end

  context 'when one drawing instruction is added' do
    renderer = USBTeensyRenderer.new("/dev/tty.usbmodem54121", 9600)
    comp = Compositor.new(renderer, [0, 0, 255, 255])
    comp.add_instruction(Line.new( TwoDPoint.new(20, 20), TwoDPoint.new(40, 40) ))
    it 'has a length of one' do
      expect(comp.drawing_instructions.length).to eq(1)
    end
    it 'has an instruction of class Line' do
      expect(comp.drawing_instructions[0].class).to eq(Line)
    end
  end

  context 'when one drawing instruction is added and drawing instructions are cleared' do
    renderer = USBTeensyRenderer.new("/dev/tty.usbmodem54121", 9600)
    comp = Compositor.new(renderer, [0, 0, 255, 255])
    comp.add_instruction(Line.new( TwoDPoint.new(20, 20), TwoDPoint.new(40, 40) ))
    comp.clear()
    it 'has a length of zero' do
      expect(comp.drawing_instructions.length).to eq(0)
    end
  end

end

2 个答案:

答案 0 :(得分:1)

这些应该会使你的规格非常紧张:

在描述块的开头将renderercomp移至let次调用。 let不会在it个示例中共享状态,从而降低意外行为的风险。请注意,它是懒惰评估,但可能有潜在的副作用。 link

describe Compositor do
  let(:renderer){ USBTeensyRenderer.new("/dev/tty.usbmodem54121", 9600) }`
  ...

在每个上下文中使用before块来封装依赖于上下文的设置

context 'when one drawing instruction is added' do
  before { comp.add_instruction(Line.new( TwoDPoint.new(20, 20),TwoDPoint.new(40, 40) )) }
  ...

内联it期望进行一次班轮测试。这应该减少滚雪球的描述。

it { expect(comp.bounding_box).to eq([0, 0, 255, 255]) }

答案 1 :(得分:0)

您可以在context下方和require 'spec_helper' describe Compositor do before do # this will run before each example even those within contexts renderer = USBTeensyRenderer.new("/dev/tty.usbmodem54121", 9600) comp = Compositor.new(renderer, [0, 0, 255, 255]) end # Or even better you can do it using let to be lazy # let(:renderer) { USBTeensyRenderer.new("/dev/tty.usbmodem54121", 9600) } # let(:comp) { Compositor.new(renderer, [0, 0, 255, 255]) } context 'when instantiated with correct parameters' do it 'has a bounding rectangle' do expect(comp.bounding_box).to eq([0, 0, 255, 255]) end it 'has a renderer' do expect(comp.renderer).to eq(renderer) end it 'has an empty array of drawing instructions' do expect(comp.drawing_instructions).to eq([]) end end context 'when one drawing instruction is added' do before do comp.add_instruction(Line.new( TwoDPoint.new(20, 20),TwoDPoint.new(40, 40) )) end it 'has a length of one' do expect(comp.drawing_instructions.length).to eq(1) end it 'has an instruction of class Line' do expect(comp.drawing_instructions[0].class).to eq(Line) end context 'and when drawing instructions are cleared' do before do comp.clear() end it 'has a length of zero' do expect(comp.drawing_instructions.length).to eq(0) end end end end 之前使用前挂钩。

{{1}}