= Person.create(name: 'alissa') > bob = Person.create(name: 'bob') > chris = Person.create(name: 'chris') > > Person.name_like('ali') > Person.younger_than(24) We have nice REPL on Rails, too.
age: 24) alisia = Person.create(name: 'alisia', age: 30) bob = Person.create(name: 'bob', age: 18) chris = Person.create(name: 'chris', age: 42) pp Person.name_like('ali') pp Person.younger_than(24) end Assert by your eye Watch output on each run.
age: 24) alisia = Person.create(name: 'alisia', age: 30) bob = Person.create(name: 'bob', age: 18) chris = Person.create(name: 'chris', age: 42) pp Person.name_like('ali') pp Person.younger_than(24) end Assertions depends on each other Must be careful to maintain data.
age: 24) alisia = Person.create(name: 'alisia', age: 30) bob = Person.create(name: 'bob', age: 18) chris = Person.create(name: 'chris', age: 42) pp Person.name_like('ali') pp Person.younger_than(24) end Assertions depends on each other It's more painful to maintain DESTRUCTIVE method's. only 1 record needed for `name_like` execution ̇ OMG: change also younger_than result
{ Person.create(name: 'alice', age: 24) } let!(:alissa){ Person.create(name: 'alissa', age: 30) } let!(:bob) { Person.create(name: 'bob', age: 18) } let!(:chris) { Person.create(name: 'chris', age: 42) } describe '.name_like' do subject { Person.name_like('ali').map(&:name) } it { should =~ %w[alice alissa] } end describe '.younger_than' do subject { Person.younger_than(24).map(&:name) } it { should =~ %w[bob] } end end end Assert Run code with test. Assert result and report obviously.
snip describe '.has_at_least_one_hobby(hobbies)' do let(:hobbies) { %w[programming BBQ travel] } subject(:people) do Person.has_at_least_one_hobby(hobbies) end end end end Not good name, especially too long.
`#any?` method to check at least one element matches condition in collection. • Then what if Person.interest_in_any(hobbies) think: Is there better name?
snip describe '.interest_in_any(hobbies)' do let(:hobbies) { %w[programming BBQ travel] } subject(:people) do Person.interest_in_any(hobbies) end end end end Looks good.
do hobbies.each do |hobby_name| Hobby.create!(name: hobby_name) end Hobby.create!(name: 'baseball') alice.hobbies << Hobby.where(name: 'travel').first bob.hobbies << Hobby.where(name: 'programming').first chris.hobbies << Hobby.where(name: 'baseball').first end subject(:people) { Person.interest_in_any(hobbies) } it { should =~ [alice, bob] } end
do hobbies.each do |hobby_name| Hobby.create!(name: hobby_name) end Hobby.create!(name: 'baseball') alice.hobbies << Hobby.where(name: 'travel').first bob.hobbies << Hobby.where(name: 'programming').first chris.hobbies << Hobby.where(name: 'baseball').first end subject(:people) { Person.interest_in_any(hobbies) } it { should =~ [alice, bob] } end If the test passes, you've DONE plain-normal case.
in Rails's controller, parameter is parsed into Hash with string value. • and I love form_for • Implement as ActiveModel form object. think: complex query
aliass(30), bob(18), chris(42)' describe '.new(name_like: "ali", younger_than: 25)' do let(:query) { PeopleQuery.new(name_like: 'ali', younger_than: 25) } subject { query.people } it { should == [alice] } end end Assert You've also got a goal for the step.
aliass(30), bob(18), chris(42)' describe '.new(name_like: "ali", younger_than: 25)' do let(:query) { PeopleQuery.new(name_like: 'ali', younger_than: 25) } subject { query.people } it { should == [alice] } end end FAQ: How much should I do test? You may test until you get a goal.
4 hobbies: programming, travel, BBQ and baseball' let(:query) { PeopleQuery.new(name_like: 'ali', hobbies: 'baseball travel') } before do alice.hobbies << Hobby.where(name: 'BBQ') alissa.hobbies << Hobby.where(name: 'baseball') end subject { query.people } it { should == [alissa] } end 3 condition handling with simple case is DONE.
it & Triangulation. • Data generation: fixture replacement • Test doubles • Assert first approach is also welcome. • Better for too difficult not to come up with solution. • But MOST IMPORTANT thing is...