-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use subject #7
Comments
RSpec 2.11 has the ability to use a named subject. So your last example can be made better with: subject(:hero) { Hero.first }
it "should be equipped with a sword" do
hero.equipment.should include "sword"
end |
The Note also that |
+1 i would consider @cupakromer's code a best practice more than subject { assigns('message') }
it { should match /it was born in Billville/ }
its(:creator) { should match /Topolino/ } |
You can see David Chelimsky's take on the matter here: http://blog.davidchelimsky.net/2012/05/13/spec-smell-explicit-use-of-subject/ |
Thoughts on using describe CommentsController do
describe '#create' do
context 'with valid form' do
let(:expect_commenting) {
expect{ post :create, comment: { user_id: 1, body: "This is a comment" } }
}
subject {
post :create, comment: { user_id: 1, body: "This is a comment" }
@controller
}
it { expect_commenting.to change{Comment.count}.by 1 }
it { should redirect_to comments_path }
it { should set_the_flash[:notice].to 'Comment Created!' }
end
end
end |
I think this should follow David Chelimsky's advice and advise using So, bad: subject { Thing.new }
it "does things" { subject.should do_things } Good: let(:thing) { Thing.new }
it "does things" { thing.should do_things } |
@therealadam in your specific example how does the Granted, you probably shouldn't used a named subject for an arbitrary object that doesn't match the |
Mechanically, they are the same. As Chelimsky points out, using |
Updated the last example and removed the example using its. For the moment I keep suggesting the usage of subject, simply because I've to read the Chelimsky. Anyone can feel free to make a pull request to change the actual definition of the guideline. |
Subject is basically syntactic sugar for a let, therefore I don't believe there's a big difference in using That being said I'm not a fan of using I prefer to use plain ruby methods to explicitly refer to the sut (or any other object), or to group a setup block and then use them as instance variables. I can live with using Does anyone agree with this? |
Doesn't the example go against Don't use should? |
Most of this is personal / project preferences. So there is no one "proper" way to handle things. If things are working for you, then keep going. @zamith can you provide an example on how you prefer ruby methods? They suffer from the same sort of "mystery guest" problem when deep nesting is involved. So I'm not sure I see what you are gaining with them. However, I have seen some crazy test files using Here's my personal preferences:
|
@cupakromer The ruby methods will be on the outer namespace, so they are global to that file. Also, they must be explicitly called, so there's no mystery guest.
as opposed to
This is a silly example, but it shows that in the first example
which is much more explicit in terms of having a setup phase and thus following the four phase test pattern |
@cupakromer I agree with most of what you're saying. |
@zamith agree with needing to be careful. However, you have the same problem with methods. If you used them across several levels of nesting, you have the same problem. Though this is getting a bit far from the topic of |
that's bullshit. if you write 1 section above that you must use "expect" syntax, then be sure to use that very syntax in this section. Otherwise people think that "expect" is bad because you make it red boxed. You transition from expect to should, which must not happen. |
If you feel like there are some inconcistencies, please, make a pull On Mon, Jun 2, 2014 at 5:54 PM, celesteking notifications@github.com
Andrea Reginato |
The BAD example is it { expect(assigns('message')).to match /it was born in Belville/ }
it { expect(assigns('message').creator).to match /Topolino/ } while the GOOD example is subject { assigns('message') }
it { should match /it was born in Billville/ } The GOOD example is missing the second test of the creator. |
I just visited this thread to check if more people considered the use of the word Just for clarifying, I'm totally ok with the subject syntax, I disagree with the use of The post http://blog.davidchelimsky.net/blog/2012/05/13/spec-smell-explicit-use-of-subject/, which some people suggested, is a great read |
Hi Diego, that makes sense.
If you think this being a best practices, send us a pull request and we'll
evaluate it.
All the best.
|
@diegoguemes yes, please submit a pull request, including that blog link in the comments! |
It seems that RSpec official docs recommend subject not be used in user facing examples.
https://www.relishapp.com/rspec/rspec-core/v/3-5/docs/subject/implicitly-defined-subject Am I getting this wrong ? |
@maximveksler note that the page is about the implicit |
How do you test a "service"/lib class? Let's say we have a class:class DomainSanitizer
def sanitize(url)
# ...
end
end
DomainSanitizer.sanitize("https://google.com") # => "google.com"
DomainSanitizer.sanitize("google.com/some_path#with_hash") # => "google.com" how would you rather test it:Without
|
a truth table is an option as well, to construct tests through code: def url(scheme, domain, path, hash)
result = ""
result += "#{scheme}://" unless scheme.nil?
result += "#{domain}" unless domain.nil?
result += "/#{path}" unless path.nil?
result += "##{hash}" unless hash.nil?
result
end
[
url("https", "google.com", "path", "hash"),
url(nil , "google.com", "path", "hash"),
url("https", "google.com", nil , "hash"),
url("https", "google.com", "path", nil ),
# .... etcccc ....
].each do |url|
# ...
end |
@Schniz Definitely the version under "Without subjects", but with multi-line |
I have three tests
This is the first time I've ever seen this test file and I'm reading these tests for the first time With the variable name "user" I don't have to guess or search or anything. It's very likely a user |
I disagree with using Another thing is when you have a lot of |
Couple of years in, I agree with not using subjects. Methods can be used to share logic and are easier to understand |
I was wondering what people think nowadays about the following article: https://benscheirman.com/2011/05/dry-up-your-rspec-files-with-subject-let-blocks/ One use case that fits nicely here, is that of controller specs, in which I need to test against different set of payloads. e.g.
The CONS I see:
The big PRO I see, is that it produces quite succinct and DRY code. I also wonder, why not just using good old helper methods? |
Personally I have always questioned the use of subject as a variable name.
Why not “data” or “thing”. It tells the reader nothing about what you are
testing.
I have to scroll up twenty lines to find out it’s a “user” or “task”.
If I show you a screen shot of a test (a full screen capture) and you can’t
tell me what subject is. The “it’s” bad code.
Quick to write painful t read
On Fri, 24 Apr 2020 at 20:35, Nicolas Sierra ***@***.***> wrote:
I was wondering what people think nowadays about the following article:
https://benscheirman.com/2011/05/dry-up-your-rspec-files-with-subject-let-blocks/
One use case that fits nicely here, is that of controller specs, in which
I need to test against different set of payloads.
e.g.
...
subject(:create_foo) { post :create, params }
...
# then being able to redefine params inside each context
let(:params) { name: 'Foogo' }
...
The CONS I see:
- a bit obscure for new developers
- it makes hard to keep track of all the redefinitions of let
- it feels uncomfortable to shadow the value in nested cases if a
default value is defined in the outmost scope.
The big PRO I see, is that it produces quite succinct and DRY code.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#7 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJ6DBSTHGEHGA4N54FCFLTROFTQFANCNFSM4ABOYG4A>
.
--
…------------------------------------------------
Life shrinks or expands in proportion to one’s courage.
-Anais Nin <http://www.curatedquotes.com/anais-nin-quotes/>
-----------------------------------------------
|
Write your thoughts about the "use subject" best practice.
The text was updated successfully, but these errors were encountered: