I'd repons by a citation from "Effective testing with RSpec 3.0" book:

The subject method defines how to build the object we’re testing. RSpec 
> gives us is_expected as shorthand for expect(subject). The phrase it 
> is_expected reads nicely in each spec here, though in larger projects we 
> tend to favor more explicit let constructs for clarity’s sake 


On Wednesday, 28 November 2018 17:37:41 UTC+1, Alexander Popov wrote:
>
> Hello,
>
> Given a class:
>
> class Person
>   def name
>     'John'
>   end
>
>   def age
>     20
>   end
> end
>
> What is the proper way to use subject?
>
> Version 1:
>
> RSpec.describe Person do
>   subject(:person) { Person.new }
>
>   it '#name' do
>     expect(person.name).to eq 'John'
>   end
>
>   it '#age' do
>     expect(person.age).to eq 20
>   end
> end
>
> Version 2:
>
> RSpec.describe Person do
>   let(:person) { Person.new }
>
>   describe '#name' do
>     subject { person.name }
>
>     it { is_expected.to eq 'John' }
>   end
>
>   describe '#age' do
>     subject { person.age }
>
>     it { is_expected.to eq 20 }
>   end
> end
>
> I think that most people have the very deeply-rooted belief that subject 
> necessarily needs to hold an instance of the class under test (Version 1). 
> This might partly come from this sentence in the documentation:
>
>
> https://relishapp.com/rspec/rspec-core/v/3-8/docs/subject/implicitly-defined-subject
>
> > If the first argument to the outermost example group is a class, an 
> instance of that class is exposed to each example via the subject method.
>
> However, I think that here the documentation simply describes what the 
> default behavior is and doesn't imply that it always has to be that way. My 
> understanding is that subject conceptually represents the thing under 
> testing. If we want to assert the result of a method call, than subject 
> better hold this result. For example, given this calss:
>
> class Person
>   attr_accessor :name
>
>   def initialize(name)
>     @name = name
>   end
>
>   def greeting
>     "Hi, #{name}!"
>   end
> end
>
> I find it more appropriate to use subject like so:
>
> RSpec.describe Person do
>   describe '#greeting' do
>     context 'when the person is called John' do
>       subject { Person.new('John').greeting }
>
>       it { is_expected.to eq 'Hi, John!' }
>     end
>
>     context 'when the person is called Merry' do
>       subject { Person.new('Merry').greeting }
>
>       it { is_expected.to eq 'Hi, Merry!' }
>     end
>   end
> end
>
> instead of:
>
> RSpec.describe Person do
>   subject(:person) { Person.new(name) }
>
>   describe '#greeting' do
>     context 'when the person is called John' do
>       let(:name) { 'John' }
>
>       it { expect(subject.greeting).to eq 'Hi, John!' }
>     end
>
>     context 'when the person is called Merry' do
>       let(:name) { 'Merry' }
>
>       it { expect(subject.greeting).to eq 'Hi, Merry!' }
>     end
>   end
> end
>
> I'd like to know what is the recommended way of using subject. Thank you 
> very much.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/rspec/d076bf62-3ad6-4046-b77e-e4fb17c62f10%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to