|
| 1 | +message <<-MARKDOWN |
| 2 | + All right, you're almost at the end! Below are a few additional concepts of testing that may helpful in your future testing adventures. |
| 3 | + |
| 4 | + ### Doubles and stubs |
| 5 | + Doubles are simpler objects that represent objects from your application. |
| 6 | + <div class="console"><pre> |
| 7 | + post = double(:post) |
| 8 | + </pre> |
| 9 | + </div> |
| 10 | + If you instantiate that double in your test file, you have access to post in your tests to test with. This is instead of creating an entire Post model in ActiveRecord. If you need to create many different test objects with different properties, FactoryGirl is a great gem for that purpose and will allow persistence or in-memory object creation, depending on your testing situation. |
| 11 | + |
| 12 | + Stubs can be used to dictate what is returned when a method is called on a double. |
| 13 | + <div class="console"><pre> |
| 14 | + post.stub(:title).and_return("Jelly") |
| 15 | + </pre> |
| 16 | + </div> |
| 17 | + So, when you write a test that calls the title attribute of the post double, you'll always get back the string Jelly. Got it? Good! |
| 18 | + |
| 19 | + ### Spies |
| 20 | + With spies, we are not talking about espionage... at least, not in relation to testing :) Spies can be used to verify whether a method was called on an object. |
| 21 | + For instance (assume you already have the post double from above): |
| 22 | + <div class="console"><pre> |
| 23 | + post = spy('post') |
| 24 | + post.content |
| 25 | + expect(post).to have_received(:content) |
| 26 | + </pre> |
| 27 | + </div> |
| 28 | + Obviously, this is a simplified case. Instead of post.content, you might have a complicated method that executes many functions internally and that's where spies can come in handy; they can check easily whether one specific method was called. Capiche? Ok, let's keep on trucking! |
| 29 | + |
| 30 | + ### Webmock |
| 31 | + What if your app relies on third-party services or applications, known amongst friends as application programming interfaces or APIs? Well, it seems like APIs should also be tested but should our test suite really be dependent on someone else? NOPE! What if the API goes down? Or is slow? Welcome to the stage: Webmock! |
| 32 | + Webmock is a gem that stubs out external HTTP requests. Once you include the gem, bundle install, and include the below code snippet in your spec helper file (which is included in every test file), you're good to go. |
| 33 | +MARKDOWN |
| 34 | +console_without_message <<-RUBY |
| 35 | +require 'webmock/rspec' |
| 36 | +WebMock.disable_net_connect!(allow_localhost: true) |
| 37 | +RUBY |
| 38 | + |
| 39 | +message <<-MARKDOWN |
| 40 | + Then, you can start stubbing out API requests in your spec helper file. Let's write an example for Bitly, a service that shortens long URLs. |
| 41 | +MARKDOWN |
| 42 | + |
| 43 | +console_without_message <<-RUBY |
| 44 | +RSpec.configure do |config| |
| 45 | + config.before(:each) do |
| 46 | + stub_request(:get, /api.bitly.com.v3.shorten/). |
| 47 | + with(headers: {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}). |
| 48 | + to_return(status: 200, body: "stubbed response", headers: {}) |
| 49 | + end |
| 50 | +end |
| 51 | +RUBY |
| 52 | + |
| 53 | +message <<-MARKDOWN |
| 54 | + So, if you write any tests in your test files that call the Bitly API, then the response will be whatever you defined above. The test will prevent the actual API request from being made. Pretty cool, huh? |
| 55 | + |
| 56 | + Awesome, you are now equipped with a license to TEST! Go forth and create doubles, stubs, and spies in your app (at least one of each and have a TA verify). |
| 57 | +MARKDOWN |
0 commit comments