Skip to content

Replace integration tests with mocked URLSession tests #130

@leogdion

Description

@leogdion

⚠️ Potential issue | 🟠 Major

Replace integration tests with mocked URLSession tests.

These integration tests have several reliability and maintainability concerns:

  1. External dependencies: Tests rely on external services (apple.com, httpbin.org) which can fail, timeout, or change behavior
  2. Flakiness: Network issues, service outages, or rate limiting will cause non-deterministic test failures
  3. CI/CD impact: Tests will fail in offline, sandboxed, or network-restricted environments
  4. Performance: Network calls significantly slow down test execution
  5. Weak assertions (lines 50, 71): Using _ = lastModified doesn't validate behavior

As per coding guidelines: "Use mock objects from BushelTestUtilities for testing protocol conformances and creating test doubles."

Recommended approach: Mock URLSession using protocol-based design

Create a protocol for URLSession operations in BushelUtilities:

public protocol URLSessionProtocol {
  func data(from url: URL) async throws -> (Data, URLResponse)
  func data(for request: URLRequest) async throws -> (Data, URLResponse)
}

extension URLSession: URLSessionProtocol {}

Then add mocks in BushelTestUtilities and test with controlled responses.

Would you like me to help implement this mocking infrastructure?

🤖 Prompt for AI Agents
In @Tests/BushelUtlitiesTests/URLSessionTests.swift around lines 38-107, The
tests in URLSessionTests (methods testFetchLastModifiedWithValidURL,
testFetchLastModifiedWithInvalidURL, testFetchLastModifiedReturnsNilGracefully,
testFetchDataWithValidURL, testFetchDataWithoutLastModifiedTracking,
testFetchDataWithInvalidURLThrows) are integration tests hitting real networks;
replace them with deterministic unit tests using a URLSessionProtocol and mocks
from BushelTestUtilities. Add a URLSessionProtocol (methods data(from:) and
data(for:)), extend URLSession to conform, create a MockURLSession in
BushelTestUtilities that returns controlled (Data, URLResponse) or throws,
update the code under test to accept a URLSessionProtocol (or provide an
injectable session on URLSession.shared wrappers like fetchLastModified and
fetchData), rewrite each test to inject the mock responses (including a
404/timeout/error case) and replace `_ = lastModified` with concrete assertions
(e.g., XCTAssertEqual/ XCTAssertNil against the mocked Last-Modified header or
data content).

Originally posted by @coderabbitai[bot] in #126 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions