Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
267 views
in Technique[技术] by (71.8m points)

rspec - Run code before before block

Rather than do this:

subject { response }
context 'when orphan' do
  before do
    post :create, asset: { parent_id: nil, uploaded_file: file }
  end

  it { should have_http_status 201 }
  it { should redirect_to_location '/' }

  it 'create a asset' do
    expect { post :create, asset: { parent_id: nil, uploaded_file: file } }.to change(Asset, :count).by(1)
  end
end

I want to be able to do this:

subject { response }
context 'when orphan' do
  before do
    post :create, asset: { parent_id: nil, uploaded_file: file }
  end

  it { should have_http_status 201 }
  it { should redirect_to_location '/' }

  it { should create_an(:asset) }
end

To do this I'll have to create a custom matcher:

RSpec::Matchers.define :create_an do |instance| 
    match do |actual|

        #### ALL I NEED IS A WAY TO TRIGGER THIS LINE
        #    BEFORE THE BEFORE BLOCK
        # before_before do
               number_before = count_records
        # end       
        ##############################################
        number_after = count_records

        number_after - number_before == 1
    end

    def count_records
        instance.to_s.classify.constantize.count
    end  

    failure_message_for_should do |actual|
        "..."
    end

    failure_message_for_should_not do |actual|
        "..."
    end

    description do
        "should create an #{instance.to_s}"
    end
end

Like I say, all I need to do is run:

number_before = count_records

before the before block,

  before do
    post :create, asset: { parent_id: nil, uploaded_file: file }
  end

is run. Is this possible? Any ideas? Any hooks rspec provides for this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't know of a way to implement what you've asked for, but the following does reduce some duplication.

context 'when orphan' do
  let(:create) { post :create, asset: { parent_id: nil, uploaded_file: file } }

  context 'the response' do
    before { create }
    subject { response }

    it { is_expected.to have_http_status 201 }
    it { is_expected.to redirect_to_location '/' }
  end

  it 'creates a asset' do
    expect { create }.to change(Asset, :count).by(1)
  end
end

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...