Hi Alexander
The recommended use of `subject` has evolved over time, so you’ll find all of
the examples you mention in use in various projects.
Our advice would be to use subject to draw attention to your “subject under
test” but also to give it a descriptive name. We would also advice using that
name, subject doesn’t mean much to a reader in context. We also advice not
using the implicit subject and to always have a doc string. What that means in
your tests depends on your implementation, if you are doing unit style tests
such as a person name, the subject is really the name, not the person.
But for example, this is how I would describe #name in your example.
```
class Person
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def name
[@first_name, @last_name].join(“ “)
end
end
RSpec.describe “Person” do
describe “#name” do
subject(:name) { Person.new(“Jon”, “Rowe”).name }
it “combines first and last names” do
expect(name).to eq “Jon Rowe"
end
end
end
```
Regards
Jon Rowe
---------------------------
[email protected]
jonrowe.co.uk
On 28 November 2018 at 16:36, 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:
>
> relishapp.com/rspec/rspec-core/v/3-8/docs/subject/implicitly-defined-subject
> (https://relishapp.com/rspec/rspec-core/v/3-8/docs/subject/implicitly-defined-subject)
>
>
> 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/dejalu-217-cb141d01-0291-466c-91d8-6649578bdafb%40jonrowe.co.uk.
For more options, visit https://groups.google.com/d/optout.