Back to Repositories

Testing Core HTTP Request Implementation in DevDocs

This test suite validates the core request functionality in the DevDocs documentation browser, focusing on HTTP request handling, response processing, and URL management. It ensures reliable network operations and proper instrumentation of request/response cycles.

Test Coverage Overview

The test suite provides comprehensive coverage of the Docs::Request class functionality, including:

  • URL handling and validation
  • Request configuration and options management
  • Response processing and instrumentation
  • Error handling and edge cases
  • Integration with Typhoeus HTTP client

Implementation Analysis

The testing approach utilizes RSpec’s behavior-driven development patterns with Minitest assertions. It employs stub responses and fake instrumentation to isolate network dependencies. The implementation leverages Typhoeus’s expectation system for HTTP request mocking.

  • Modular test structure with describe/it blocks
  • Before/after hooks for test state management
  • Stub response generation and cleanup
  • Dynamic request configuration testing

Technical Details

  • Testing Framework: Minitest
  • HTTP Client: Typhoeus
  • Mocking System: Typhoeus::Expectation
  • Custom Extensions: FakeInstrumentation module
  • Test Helpers: Custom request wrapper methods

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices through isolated test cases, proper setup/teardown patterns, and comprehensive edge case coverage. It demonstrates effective use of Ruby testing patterns and maintainable test organization.

  • Isolated test cases with clear assertions
  • Proper test cleanup and state management
  • Comprehensive mock object usage
  • Clear test case organization and naming

freecodecamp/devdocs

test/lib/docs/core/request_test.rb

            
require_relative '../../../test_helper'
require_relative '../../../../lib/docs'

class DocsRequestTest < Minitest::Spec
  let :url do
    'http://example.com'
  end

  def request(url = self.url, **options)
    Docs::Request.new(url, **options).tap do |request|
      request.extend FakeInstrumentation
    end
  end

  let :response do
    Typhoeus::Response.new.tap do |response|
      Typhoeus.stub(url).and_return(response)
    end
  end

  after do
    Typhoeus::Expectation.clear
  end

  describe ".run" do
    before { response }

    it "makes a request and returns the response" do
      assert_equal response, Docs::Request.run(url)
    end

    it "calls the given block with the response" do
      Docs::Request.run(url) { |arg| @arg = arg }
      assert_equal response, @arg
    end
  end

  describe ".new" do
    it "accepts a Docs::URL" do
      url = Docs::URL.parse 'http://example.com'
      assert_equal url.to_s, request(url).base_url
    end

    it "defaults :followlocation to true" do
      assert request.options[:followlocation]
      refute request(url, followlocation: false).options[:followlocation]
    end
  end

  describe "#run" do
    before { response }

    it "instruments 'response'" do
      req = request.tap(&:run)
      assert req.last_instrumentation
      assert_equal 'response.request', req.last_instrumentation[:event]
      assert_equal url, req.last_instrumentation[:payload][:url]
      assert_equal response, req.last_instrumentation[:payload][:response]
    end
  end

  describe "#response=" do
    it "extends the object with Docs::Response" do
      response = Object.new
      request.response = response
      assert_includes response.singleton_class.ancestors, Docs::Response
    end
  end
end