Mock fastly::http::CandidateResponse

Request for CandidateResponse testing/mocking support in Fastly Rust SDK

Motivation

I’m working on a Compute application where I need to thoroughly test functions that manipulate cache behavior via CandidateResponse. For example, I have a function that applies specific cache control rules:

fn apply_cache_control_rules(resp: &mut CandidateResponse) {
    if let Some(surrogate_control) = resp.get_header_str("surrogate-control") {
        if surrogate_control.contains("no-cache") {
            resp.set_ttl(Duration::from_secs(0));
        }
        if surrogate_control.contains("no-store") {
            resp.set_header("surrogate-control", "no-store, private");
            resp.set_uncacheable(true);
        }
    }
}

fn main() -> Result<(), Error> {
    let mut req = Request::from_client();

    let beresp = req.send("backend")?;

    req.set_after_send(|resp: &mut CandidateResponse| {
        apply_cache_control_rules(resp);
    });

    Ok(beresp.send_to_client())
}

Current Testing Options and Their Limitations

I’m currently facing significant challenges when trying to test this code:

  1. Integration tests with Viceroy:
    While Viceroy is excellent for testing end-to-end functionality, it doesn’t allow access to Request::set_after_send.

  2. Unit tests:
    For unit testing, I need to create a mock implementation of CandidateResponse. However, the current SDK design makes this exceptionally difficult:

    • CandidateResponse::new() requires several internal Fastly-specific types (HttpCacheHandle, CacheOverride, ResponseHandle, Body) which aren’t designed for mocking
      • The members depend on private crates that are not exposed to users, making it impossible to create compatible mock implementations
    • There’s no trait or interface that defines the behavior of CandidateResponse that could be implemented by a test double

Feature Request

Could the Fastly Rust SDK team consider adding mocking capabilities for CandidateResponse and similar structures? This would greatly improve the testability of Compute applications. Some potential solutions might include:

  1. Providing mock implementations of the required dependencies for CandidateResponse::new()
  2. Adding a dedicated test utility for creating stub/mock instances of CandidateResponse
2 Likes

This is a really solid example stub and write up @arayaryoma. I really appreciate the time you took to build this out. I’ll pass this on to to the team as a feature request.