1
\$\begingroup\$

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{</?[^>]+?>}, '').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(&:content).should == ["Some super question?", "Some extra question?"]
 end
 it "excludes not matching results" do
 Search.new("extra", [76]).results.map(&:content).should == ["Some extra question?"]
 end
 it "returns no matches" do
 Search.new("hiper", [76]).results.map(&:content).should == []
 end
 it "should filter results by app" do
 Search.new("some", [77]).results.map(&:content).should == []
 end
 end
 describe "#autocomplete" do
 it "returns array with matching items" do
 Search.new("super", [76]).autocomplete.should == 
 [{
 :title=>@question1.content,
 :label=>"Some <span class=\"bold\">super</span> question? <span class=\"search-type\">Question</span>",
 :value=>"/Marketing/q/#{@question1.id}"
 }]
 end
 end
 describe "#strip_tags" do
 it "should strip title" do
 Search.new("super", [76]).strip_tags("<p>Some text</p> ").should == "Some text"
 end
 end

Is there a better way to test that methods in service class ?

asked Dec 26, 2012 at 17:30
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

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(&: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).

answered Dec 29, 2012 at 4:24
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.