model rspec writing

13 views
Skip to first unread message

Ashwini Rane

unread,
Oct 11, 2020, 1:33:13 PM10/11/20
to rspec
Hi,
I am a beginner in ruby and rails and struggling to write rspec code for my model methods as given below:

Please help me write rspec implementation and test examples for my methods for me to have a basic understanding of how can I proceed in this:

def get_quarantine_trails(event_id)
quarantine_event_result = quarantine_events.find_by(id: event_id)
quarantine_event_result.inventory_items.select([:item_number, :id])
end

def quarantine_events_list
quarantine_events.joins(:quarantine_trails).
select('quarantine_events.*,count(quarantine_trails.quarantine_event_id) as count_of_events').
end


Here: quarantine_events and quarantine_trails are 2 models where they have direct association in between them. quarantine_events table being my parent table and quarantine_trails being my child table.
inventory_items is another model having association with quarantine_trail table.

Help me create a rspec implementation for this 2 methods for my initial understanding.

Thank you.

Jack Royal-Gordon

unread,
Oct 11, 2020, 4:14:35 PM10/11/20
to rs...@googlegroups.com
This is the tip of a very large iceberg. I recommend you at least scan through one of the many excellent RSpec books available out there before you start writing tests with RSpec. If you’re new to programming/testing, you should probably read it cover to cover. I used "Effective Testing with RSpec 3” to help me when I was first learning RSpec 3 (actually, it was RSpec 2 when I read it).

If you really embrace the TDD/BDD (Test-driven design/Behavior-driven design) scheme that RSpec represents, you will end up writing the tests BEFORE you write the code, not after. RSPec should not generally be an afterthought. However, from time to time you may be presented with a project in progress that needs tests written, so it’s not like that will never happen. More to the point, when you write a test you should focus first on what you are trying to accomplish with the code and only once you’ve done that worry about how the code is accomplishing it and therefore how to test it.

From the code you included, I am concluding that somewhere in the “QuarantineEvent” model you have a declaration like
has_many :quarantine_trails

This statement is sufficient to establish the relationship and should not need to be tested. However, if you want to add a test to ensure that future programmers (including yourself) do not somehow screw up this relationship, the “shoulda” gem offers excellent one-line association tests (the RSpec world disagrees over whether these sorts of tests are necessary; feel free to google this, read the arguments, and decide for yourself). Anyway, if you add in the “shouda” gem, you can just write the test as follows:
it “has a one-to-many association with QuarantineEvent
   expect(QuarantineEvent).to have_many :quarantine_trails
end
or, if written inside a “describe QuarantineEvent” block:
it { is_expected.to have_many :quarantine_trails }

But that’s just the beginning. Are those methods part of a model, helper, or controller? Each has it’s own unique testing needs.  For a controller, you’ll be testing web requests that come in (e.g. GET “quarantine events/id”); if this is a function that supports such a request, then testing the request itself may be sufficient. If you want additional tests, then you can use the same style of test as you would for a helper or model.

Here is what your test file might look like (I just coded some tests for the first method):

require ’spec_helper.rb # Configuration + test helpers

describe model/controller/helper-class-name do  # (e.g. QuarantineEvent)
    before(:each) do # setup data for test
<create some quarantine events, inventory items and quarantine trails>
let(:good_event_id) { <id of event with quarantine trails> } # Creates variables available in the examples
let(: good_invoice_item_id_list) { …} # List of expected invoice item IDs
let(:bad_event_id) { <id not matching any event> }
    end

    describe ‘get_quarantine_trails’ do # method name being tested
it ‘returns a list of inventory items belonging to the id’ do # describe one expected behavior
    expect(get_quarantine_trails(good_event_id).map(&:id)).to include(good_invoice_item_id_list)
# This is the actual test
end

it ‘returns an empty list for invalid event id’ do
    expect(get_quarantine_trails(bad_event_id)).to be_empty
end

… # add more tests if you want - each one will get a fresh copy of the data create in the “before" block
    end

    describe ‘quarantine_events_list do
    end
end

Note that the test is fairly readable (at least the major elements are). 
As you can see, there’s a lot here that doesn’t really look like “normal” Ruby. Examples of these elements are “describe”, “before”, “let”, “it”, and “expect”. These are all defined as part of RSpec, and you really need to understand them before you start writing tests with RSpec. Not only that, but there are a number of ways to accomplish the creation of test records (for example, FactoryBot) that are full subjects on their own. And there are a lot more elements to RSpec than I’ve mentioned here — it’s a large subject.


--
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 rspec+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/f6fe1bad-9992-46b1-be79-5eb7849abe82n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages