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.