简体   繁体   English

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

[英]how to use the context in the tests?

please help write tests with context. 请帮助编写具有上下文的测试。

model Album: 模特专辑:

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

I wrote tests for model Album: 我为模型Album编写了测试:

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

these tests worked OK. 这些测试工作正常。 but i need use context: 但我需要使用上下文:

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

but these tests is not DRY. 但是这些测试不是DRY。 please help write the test with context again. 请帮助再次编写带有上下文的测试。

ps: good practices that I tried to use: ps:我尝试使用的良好做法:

  1. checking limiting cases (a very small value, very great value, average value) 检查极限情况(很小的值,很大的值,平均值)
  2. use contexts for the organization code 使用上下文作为组织代码
  3. each test should be in a separate method 每个测试应采用单独的方法

Your tests using context looks okay. 使用context测试看起来还可以。 But, you can write better tests using context by following the best practices. 但是,您可以通过遵循最佳实践来使用context编写更好的测试。 See better specs guidelines to see how to write better RSpec tests. 请参阅更好的规格指南,以了解如何编写更好的RSpec测试。

Also, see the following classic example of using context from the The RSpec Style Guide 另外,请参阅《 RSpec样式指南》中的以下使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM