如何在测试中使用上下文?

时间:2015-08-31 09:20:15

标签: ruby-on-rails ruby-on-rails-4 rspec rspec2

请帮助用上下文编写测试。

模特专辑:

class Album < ActiveRecord::Base
  validates :title, presence: true, length: { maximum:  50, minimum: 3 }, uniqueness: { case_sensitive: false }
  validates :description, presence: true, length: { maximum:  600, minimum: 10 }
end

我为模特专辑写了测试:

describe Album do
  it "has a valid factory" do
    expect(FactoryGirl.create(:album)).to be_valid
  end

  it "is invalid without title" do
    expect(FactoryGirl.build(:album, title: nil)).not_to be_valid
  end  

  it "is invalid with duplicate title" do
    FactoryGirl.create(:album, title: 'qwerty')
    expect(FactoryGirl.build(:album, title: 'qwerty')).not_to be_valid
  end 

  it "is valid with different title" do
    FactoryGirl.create(:album, title: 'zxcvbn')
    expect(FactoryGirl.build(:album, title: 'asdfgh')).to be_valid
  end        
end

这些测试工作正常。但我需要使用上下文:

describe Album do
  it "has a valid factory" do
    expect(FactoryGirl.create(:album)).to be_valid
  end

  describe '#title' do
    context "invalid" do
      it "is invalid without title" do
        expect(FactoryGirl.build(:album, title: nil)).not_to be_valid
      end  

      it "is invalid with long title" do
        expect(FactoryGirl.build(:album, title: 'If you liked my series on practical advice for adding reliable tests to your Rails apps, check out the expanded ebook version. Lots of additional, exclusive content and a complete sample Rails application.')).not_to be_valid
      end        

      it "is invalid with duplicate title" do
        FactoryGirl.create(:album, title: 'qwerty')
        expect(FactoryGirl.build(:album, title: 'qwerty')).not_to be_valid
      end       
    end

    context "valid" do
      it "is valid with title" do
        expect(FactoryGirl.build(:album, title: 'good title')).not_to be_valid
      end  

      it "is valid with different title" do
        FactoryGirl.create(:album, title: 'zxcvbn')
        expect(FactoryGirl.build(:album, title: 'asdfgh')).to be_valid
      end  
    end
  end      
end

但这些测试不是DRY。请帮助再次使用上下文编写测试。

PS: 我试图使用的良好做法:

  1. 检查限制案例(一个非常小的值,非常大的价值, 平均值)
  2. 将组织代码用于上下文
  3. 每项测试应采用单独的方法

1 个答案:

答案 0 :(得分:1)

使用context的测试看起来没问题。但是,您可以按照最佳实践使用context编写更好的测试。请参阅better specs指南,了解如何编写更好的RSpec测试。

另外,请参阅以下使用The RSpec Style Guide

中的context的经典示例
# A classic example for use of contexts in a controller spec is creation or update when the object saves successfully or not.

describe ArticlesController do
  let(:article) { mock_model(Article) }

  describe 'POST create' do
    before { Article.stub(:new).and_return(article) }

    it 'creates a new article with the given attributes' do
      Article.should_receive(:new).with(title: 'The New Article Title').and_return(article)
      post :create, article: { title: 'The New Article Title' }
    end

    it 'saves the article' do
      article.should_receive(:save)
      post :create
    end

    context 'when the article saves successfully' do
      before { article.stub(:save).and_return(true) }

      it 'sets a flash[:notice] message' do
        post :create
        flash[:notice].should eq('The article was saved successfully.')
      end

      it 'redirects to the Articles index' do
        post :create
        response.should redirect_to(action: 'index')
      end
    end

    context 'when the article fails to save' do
      before { article.stub(:save).and_return(false) }

      it 'assigns @article' do
        post :create
        assigns[:article].should be_eql(article)
      end

      it 're-renders the "new" template' do
        post :create
        response.should render_template('new')
      end
    end
  end
end