Refactor specs for service class methods Service Class

# services/search.rb

class Search
  include Rails.application.routes.url_helpers
  include ActionView::Helpers::TagHelper

  def initialize(term, app_ids)
    @term = term
    @app_ids = app_ids
  end

  def results
    term = @term
    app_ids = @app_ids

    multi_search = Tire.multi_search do
      no_app_indices = [Event, PastEvent, Review].map {|c| c.tire.index_name}
      search :without_app, indices: no_app_indices do
        query { string term }
      end

      app_indices = [Question, Answer, Link, ServiceProvider].map {|c| c.tire.index_name}
      search :with_app, indices: indices do
        query do
          filtered do
            query { string term }
            filter :terms, app_id: app_ids
          end
        end
      end
    end
    multi_search.results[:with_app].to_a + multi_search.results[:without_app].to_a
  end

  def autocomplete
    results.map do |result|
      title, caption, route = set_item_based_on_type(result)
      {title: strip_tags(title), label: set_label(strip_tags(title), caption), value: route}
    end
  end

  def strip_tags(title)
    title.gsub(%r{&lt;/?[^&gt;]+?&gt;}, '').strip
  end


Specs

describe Search do
  before(:all) do
    Question.index.delete
    Question.tire.create_elasticsearch_index

    @question1 = create :question, content: "Some super question?"
    @question2 = create :question, content: "Some extra question?"

    app = create :app, name: "Marketing", id: 76
    @question1 = create :question, content: "Some super question?", app: app
    @question2 = create :question, content: "Some extra question?", app: app

    # wait for indexing to finish
    sleep 1
  end

  describe "#results" do
    it "returns matched results" do
      Search.new("Some", [76]).results.map(&amp;:content).should == ["Some super question?", "Some extra question?"]
    end

    it "excludes not matching results" do
      Search.new("extra", [76]).results.map(&amp;:content).should == ["Some extra question?"]
    end

    it "returns no matches" do
      Search.new("hiper", [76]).results.map(&amp;:content).should == []
    end

    it "should filter results by app" do
      Search.new("some", [77]).results.map(&amp;:content).should == []
    end
  end

  describe "#autocomplete" do
    it "returns array with matching items" do
      Search.new("super", [76]).autocomplete.should ==  
        [{
          :title=&gt;@question1.content,
          :label=&gt;"Some &lt;span class=\"bold\"&gt;super&lt;/span&gt; question? &lt;span class=\"search-type\"&gt;Question&lt;/span&gt;",
          :value=&gt;"/Marketing/q/#{@question1.id}"
        }]
    end
  end

  describe "#strip_tags" do
    it "should strip title" do
      Search.new("super", [76]).strip_tags("&lt;p&gt;Some text&lt;/p&gt; ").should == "Some text"
    end
  end


Is there a better way to test that methods in service class ?
Use let (or let!) to set up your fixtures instead of the instance variables. 

let!(:app)        { create :app, name: "Marketing", id: 76 }
let!(:question1)  { create :question, content: "Some super question?" }
let!(:question2)  { create :question, content: "Some extra question?" }
let!(:with_app1)  { create :question, content: "Some super question?", app: app }
let!(:with_app2)  { create :question, content: "Some extra question?", app: app }


Use subject (in combination with let). Here are some examples:

describe "#results" do
  subject { Search.new(keyword, [app_id]).results.map(&amp;:content) }

  context "existing app_id" do
    let(:app_id) { 76 }

    context "multiple matches" do
      let(:keyword) { "Some" }

      its(:size) { should == 2 }
      it { should include(with_app1.content) }
      it { should include(with_app2.content) }
    end

    context "single matches" do
      let(:keyword) { "extra" }

      its(:size) { should == 1 }
      it { should include(with_app2.content) }
    end

    context "no matches" do
      let(:keyword) { "hiper" }

      it { should be_empty }
    end
  end

  context "non-exisiting app_id" do
    let(:keyword) { "some" }
    let(:app_id)  { 123 }

    it { should be_empty }
  end
end


You will end up with more code if you follow this through, but also with more and finer grained examples (each it or its block is a single example).