Skip to content

Commit

Permalink
add article for described class
Browse files Browse the repository at this point in the history
  • Loading branch information
glaucocustodio committed Aug 3, 2024
1 parent e7c4180 commit ac08109
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 57 deletions.
3 changes: 3 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ nav_external_links:
- title: Use contexts
url: "#use-contexts"
hide_icon: true
- title: Leverage described class
url: "#leverage-described-class"
hide_icon: true
- title: Short description
url: "#short-description"
hide_icon: true
Expand Down
12 changes: 6 additions & 6 deletions _includes/all_possible_cases.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ <h2 id="all-possible-cases">
</a>
</h2>

<p>Testing is a good practice, but if you do not test the edge cases, it will not be useful. Test valid, edge and invalid case. For example, consider the following action..</p>
<p>Testing is a good practice, but if you do not test the edge cases, it will not be useful. Test valid, edge and invalid cases.</p>

<p class="note alert">If you have way too many cases to test, it might be an indication your subject class is doing too much and must be break down into other classes.</p>

Expand All @@ -23,8 +23,8 @@ <h2 id="all-possible-cases">

<div class="bad">
{% highlight ruby %}
describe '#destroy' do
context 'when product exists' do
describe 'DELETE /:id' do
context 'when the product exists' do
it 'deletes the product' do
end
end
Expand All @@ -34,13 +34,13 @@ <h2 id="all-possible-cases">

<div class="good">
{% highlight ruby %}
describe '#destroy' do
context 'when product exists' do
describe 'DELETE /:id' do
context 'when the product exists' do
it 'deletes the product' do
end
end

context 'when product does not exist' do
context 'when the product does not exist' do
it 'raises 404' do
end
end
Expand Down
31 changes: 22 additions & 9 deletions _includes/avoid_hooks.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,28 @@ <h2 id="avoid-hooks">
</a>
</h2>

<p>Avoid hooks whenever possible since they tend to make your tests complicated over time.</p>
<p>Avoid hooks since they usually cause your tests to become more complex in the long run.</p>

<div class="bad">
{% highlight ruby %}
describe '#index' do
describe 'GET /' do
context 'when user is authenticated' do
before do
@user = create(:user)
sign_in @user
get profile_path
end

context 'when user is admin' do
context 'when user has a profile' do
it 'returns 200' do
create(:profile, user: @user)
expect(response.code).to eq('200')
end
end

context 'when user is not admin' do
it 'returns 401' do
context 'when user does not have a profile' do
it 'returns 404' do
expect(response.code).to eq('404')
end
end
end
Expand All @@ -32,19 +36,28 @@ <h2 id="avoid-hooks">

<div class="good">
{% highlight ruby %}
describe '#index' do
describe 'GET /' do
context 'when user is authenticated' do
context 'when user is admin' do
context 'when user has a profile' do
it 'returns 200' do
user = create(:user)
create(:profile, user: user)
sign_in user

get profile_path

expect(response.code).to eq('200')
end
end

context 'when user is not admin' do
it 'returns 401' do
context 'when user does not have a profile' do
it 'returns 404' do
user = create(:user)
sign_in user

get profile_path

expect(response.code).to eq('404')
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions _includes/create_only_the_data_you_need.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@ <h2 id="create-only-the-data-you-need">

<div class="bad">
{% highlight ruby %}
describe '#featured_product' do
describe '.featured_product' do
it 'returns the featured product' do
create_list(:product, 5)
product_featured = create(:product, featured: true)

expect(subject.featured_product).to eq(product_featured)
expect(described_class.featured_product).to eq(product_featured)
end
end
{% endhighlight %}
</div>

<div class="good">
{% highlight ruby %}
describe '#featured_product' do
describe '.featured_product' do
it 'returns the featured product' do
product_non_featured = create(:product, featured: false)
create(:product, featured: false)
product_featured = create(:product, featured: true)

expect(subject.featured_product).to eq(product_featured)
expect(described_class.featured_product).to eq(product_featured)
end
end
{% endhighlight %}
Expand Down
18 changes: 17 additions & 1 deletion _includes/describe.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ <h2 id="describe">
</a>
</h2>

<p>Be clear about what method you are describing. For instance, use the Ruby documentation convention of <code>.</code> when referring to a class method's name and <code>#</code> when referring to an instance method's name.</p>
<p>Be clear about what you are testing.</p>

<div class="bad">
{% highlight ruby %}
Expand All @@ -19,6 +19,8 @@ <h2 id="describe">
{% endhighlight %}
</div>

<p>Use the Ruby documentation convention of <code>.</code> when referring to a class method's name and <code>#</code> when referring to an instance method's name.</p>

<div class="good">
{% highlight ruby %}
describe User do
Expand All @@ -28,6 +30,20 @@ <h2 id="describe">
describe '#admin?' do
end
end
{% endhighlight %}
</div>

<p>In request tests, describe the methods and paths under test.</p>

<div class="good">
{% highlight ruby %}
describe UsersController, type: :request do
describe 'POST /' do
end

describe 'GET /' do
end
end
{% endhighlight %}
</div>
</article>
49 changes: 49 additions & 0 deletions _includes/described_class.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<article>
<h2 id="leverage-described-class">
<a href="#leverage-described-class">
Leverage described class
</a>
</h2>

<p>Tests are not supposed to be DRY, but that doesn't mean we need to repeat ourselves in vain. Leverage <code>described_class</code> to make your tests maintainable over time.</p>

<div class="bad">
{% highlight ruby %}
describe Pilot do
describe '.most_successful' do
it 'returns the most successful pilot' do
senna = create(:pilot, name: 'Ayrton Senna')
create(:pilot, name: 'Alain Prost')
create(:race, winner: senna)

most_successful_pilot = Pilot.most_successful

expect(most_successful_pilot.name).to eq('Ayrton Senna')
end
end
end
{% endhighlight %}
</div>


<div class="good">
{% highlight ruby %}
describe Pilot do
describe '.most_successful' do
it 'returns the most successful pilot' do
senna = create(:pilot, name: 'Ayrton Senna')
create(:pilot, name: 'Alain Prost')
create(:race, winner: senna)

most_successful_pilot = described_class.most_successful

expect(most_successful_pilot.name).to eq('Ayrton Senna')
end
end
end
{% endhighlight %}
</div>


<p>If the class <code>Pilot</code> ever gets renamed, one just need to change it at the top level <code>describe</code>.</p>
</article>
16 changes: 8 additions & 8 deletions _includes/dont_use_shared_examples.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ <h2 id="dont-use-shared-examples">
<div class="bad">
{% highlight ruby %}
shared_examples 'a normal dog' do
it { is_expected.to be_able_to_jump }
it { is_expected.to be_able_to_bark }
end

RSpec.describe Dog do
subject { described_class.new(able_to_jump?: true, able_to_bark?: true) }
describe Dog do
subject { described_class.new(able_to_bark?: true) }
it_behaves_like 'a normal dog'
end
{% endhighlight %}
</div>

<div class="good">
{% highlight ruby %}
RSpec.describe Dog do
it 'barks and jumps' do
subject = described_class.new(able_to_jump?: true, able_to_bark?: true)
describe Dog do
describe '#able_to_bark?' do
it 'barks' do
subject = described_class.new(able_to_bark?: true)

expect(subject).to be_able_to_jump
expect(subject).to be_able_to_bark
expect(subject.able_to_bark?).to eq(true)
end
end
end
{% endhighlight %}
Expand Down
14 changes: 8 additions & 6 deletions _includes/factories_not_fixtures.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ <h2 id="factories-not-fixtures">
</a>
</h2>

<p><a href="https://github.com/thoughtbot/factory_bot" target="_blank">Factories</a> are more flexible and easy to work with.</p>
<p><a href="https://github.com/thoughtbot/factory_bot" target="_blank">Factories</a> are more flexible and easier to work with.</p>

<div class="example">
{% highlight ruby %}
def name
def full_name
"#{first_name} #{last_name}"
end
{% endhighlight %}
Expand All @@ -18,8 +18,9 @@ <h2 id="factories-not-fixtures">
<div class="good">
{% highlight ruby %}
it 'returns the full name' do
user = create(:user, fist_name: 'Ayrton', last_name: 'Senna')
expect(user.name).to eq('Ayrton Senna')
user = create(:user, fist_name: 'Santos', last_name: 'Dumont')

expect(user.full_name).to eq('Santos Dumont')
end
{% endhighlight %}
</div>
Expand All @@ -29,8 +30,9 @@ <h2 id="factories-not-fixtures">
<div class="good">
{% highlight ruby %}
it 'returns the full name' do
user = build_stubbed(:user, fist_name: 'Ayrton', last_name: 'Senna')
expect(user.name).to eq('Ayrton Senna')
user = build_stubbed(:user, fist_name: 'Santos', last_name: 'Dumont')

expect(user.full_name).to eq('Santos Dumont')
end
{% endhighlight %}
</div>
Expand Down
2 changes: 1 addition & 1 deletion _includes/group_expectations.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ <h2 id="group-expectations">
</h2>

<p>
Having an <code>it</code> for each expectation can lead to a terrible test performance. Try to group expectations that
Having an <code>it</code> for each expectation can lead to a terrible test performance. Group expectations that
use a similar data setup to improve performance and make the tests more readable.
</p>

Expand Down
4 changes: 2 additions & 2 deletions _includes/instance_double_over_double.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h2 id="instance-double-over-double">
<div class="bad">
{% highlight ruby %}
it "passes" do
user = double(:user, name: "Ayrton Senna")
user = double(:user, name: "Gustavo Kuerten")
puts user.name
end
{% endhighlight %}
Expand All @@ -29,7 +29,7 @@ <h2 id="instance-double-over-double">
<div class="good">
{% highlight ruby %}
it "fails" do
user = instance_double(User, name: "Ayrton Senna")
user = instance_double(User, name: "Gustavo Kuerten")
puts user.name
end
{% endhighlight %}
Expand Down
22 changes: 12 additions & 10 deletions _includes/lets_not.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ <h2 id="lets-not">
</a>
</h2>

<p>Do not use <code>let</code> / <code>let!</code>. These tend to turn your tests very complicated over time as one needs to look up variables defined then apply deltas to figure their current state. Read more <a href="https://thoughtbot.com/blog/lets-not">here</a>.</p>
<p>Do not use <code>let</code> / <code>let!</code>. These tend to turn your tests very complicated over time as one needs to look up variables defined then apply deltas to figure their current state. Understand more <a href="https://thoughtbot.com/blog/lets-not">here</a>.</p>

<p class="note info">Tests are not supposed to be DRY, but easy to read and maintain.</p>

<div class="bad">
{% highlight ruby %}

describe '#name' do
let(:user) { create(:user, fist_name: 'Ayrton', last_name: 'Senna') }
describe '#full_name' do
let(:user) { create(:user, fist_name: 'Edson', last_name: 'Pelé') }

context 'when first name and last name are present' do
it 'returns the full name' do
expect(user.name).to eq('Ayrton Senna')
expect(user.full_name).to eq('Edson Pelé')
end
end

context 'when last name is not present' do
it 'returns the first name' do
user.last_name = nil
expect(user.name).to eq('Ayrton')
expect(user.full_name).to eq('Edson')
end
end
end
Expand All @@ -33,18 +33,20 @@ <h2 id="lets-not">

<div class="good">
{% highlight ruby %}
describe '#name' do
describe '#full_name' do
context 'when first name and last name are present' do
it 'returns the full name' do
user = create(:user, fist_name: 'Ayrton', last_name: 'Senna')
expect(user.name).to eq('Ayrton Senna')
user = create(:user, fist_name: 'Edson', last_name: 'Pelé')

expect(user.full_name).to eq('Edson Pelé')
end
end

context 'when last name is not present' do
it 'returns the first name' do
user = create(:user, fist_name: 'Ayrton', last_name: nil)
expect(user.name).to eq('Ayrton')
user = create(:user, fist_name: 'Edson', last_name: nil)

expect(user.full_name).to eq('Edson')
end
end
end
Expand Down
Loading

0 comments on commit ac08109

Please sign in to comment.