为案例陈述设置属性编写最小测试规范模型测试

时间:2018-12-03 18:15:50

标签: ruby-on-rails ruby switch-statement minitest

我正在minitest-spec中为以下模型方法编写模型测试:

  def self.attributes_for_state(state)
    case state
    when :closed
      attributes = {
        active: false,
        selected: false,
        staged: false,
      }
    when :selected
      attributes = {
        active: true,
        selected: true,
        selected_at: Time.zone.now,
        staged: false,
        staged_at: nil,
      }
  else
      raise "Invalid state choice, no attributes defined for #{state}"
    end
  end

我写了一个较早的测试,其中属性的if语句确定了状态,但是该语句被翻转了-状态决定了属性。如何为属性列表设置案例说明?我有一个主意(如下),但这很模糊:

假设我坚持我的规格文件(describe / it)中其他测试的结构

describe "#attributes_for_state" do
  it "returns closed attributes when state is :closed" do
     # attributes_for_state(state)
    create ps = :product_selection, :closed #Factory/trait not registered
    assert_equal(ps.attributes_for_state(:closed), {active: false, selected: false, staged: false, staging: false, destaging: false,})
end

    end
    it "should have :selected attributes" do

    end
    it "should have :staged attributes" do

    end        
  end

工厂,以供参考:

factory :product_selection do
  account {|ps| ps.association(:account) }
  user {|ps| ps.association(:user) }

 active { true }
 selected { false }
 staging { false }
 staged { false }
 staged_at { nil }    
end

1 个答案:

答案 0 :(得分:0)

我通常会这样安排规格:

describe 'method name' do
  subject { ... }

  context 'when some condition' do
    //define vars with 'let'

    //setup the mocks in a 'before' hook (only before each)

    it 'does something' do
      // Just check that the subject is what you expect
    end
  end
end

此外,如果我真的不是真的需要它,我也不会创建真实的对象,而只需使用double

所以您可以做到的一种方法是这样:

describe "#attributes_for_state" do
  subject { described_class.attributes_for_state(state) }

  context 'when closed' do
    let(:state) { :closed }
    let(:expected_attr) do
      {
        active: false,
        selected: false,
        staged: false,
      }
    end
    it { should eq expected_attr }
  end

  context 'when selected' do
    let(:time_zone) { double(now: time) }
    let(:time) { 'some_time' }
    let(:state) { :selected }
    let(:expected_attr) do
      {
        active: true,
        selected: true,
        selected_at: time,
        staged: false,
        staged_at: nil,
      }
    end

    before do
      allow(Time).to receive(:zone).and_return(time_zone)
    end

    it { should eq expected_attr }
  end
end

基本上,上面的描述应该使用方法名称,上下文是将测试分为不同的情况,一个很好的经验法则是,始终以“ when”和“ with”之类的词开始上下文。

使用主题来指示您要测试的内容,在这种情况下,它是方法的结果,每个上下文定义其状态和预期的属性。

您还可以检查未定义状态:

context 'when not defined' do
  let(:state) { "some_not_defined_state" }

  it 'raises runtime error' do
    expect { subject }.to raise_error(RuntimeError)
  end
end

检查引发错误时,重要的是要具体说明您期望的错误类型...

编辑: 像这样安排规范时,好处是当您使用guard运行它时,会得到一些代码文档:

enter image description here