EasyVCR is a library for recording and replaying HTTP interactions in your test suite.
This can be useful for speeding up your test suite, or for running your tests on a CI server which doesn't have connectivity to the HTTP endpoints you need to interact with.
Run your test suite locally against a real HTTP endpoint in recording mode
using EasyVCR;
// Create a cassette to handle HTTP interactions
var cassette = new Cassette("path/to/cassettes", "my_cassette");
// create an EasyVcrHttpClient using the cassette
var recordingHttpClient = HttpClients.NewHttpClient(cassette, Mode.Record);
// Use this EasyVcrHttpClient in any class making HTTP calls
// Note: EasyVcrHttpClient implements HttpClient, so it can be used anywhere a HttpClient is expected
// For example, RestSharp v107+ supports custom HTTP clients
RestClient restClient = new RestClient(recordingHttpClient, new RestClientOptions()));
// Or make HTTP calls directly
var response = await recordingHttpClient.GetAsync("https://api.example.com/v1/users");
Real HTTP calls will be made and recorded to the cassette file.
Switch to replay mode:
using EasyVCR;
// Create a cassette to handle HTTP interactions
var cassette = new Cassette("path/to/cassettes", "my_cassette");
// create an EasyVcrHttpClient using the cassette
var replayingHttpClient = HttpClients.NewHttpClient(cassette, Mode.Replay);
Now when tests are run, no real HTTP calls will be made. Instead, the HTTP responses will be replayed from the cassette file.
Mode.Auto
: Play back a request if it has been recorded before, or record a new one if not. (default mode forVCR
)Mode.Record
: Record a request, including overwriting any existing matching recording.Mode.Replay
: Replay a request. Throws an exception if no matching recording is found.Mode.Bypass
: Do not record or replay any requests (client will behave like a normal HttpClient).
EasyVCR
comes with a number of features, many of which can be customized via the AdvancedOptions
class.
Censor sensitive data in the request and response, such as API keys and auth tokens.
Can censor:
- Request and response headers (via key name)
- Request and response bodies (via key name) (JSON only)
- Request query parameters (via key name)
- Request URL path elements (via regex pattern matching)
Default: Disabled
using EasyVCR;
var cassette = new Cassette("path/to/cassettes", "my_cassette");
var censors = new Censors().CensorHeadersByKeys(new List<string> { "Authorization" }) // Hide the Authorization header
censors.CensorBodyElementsByKeys(new List<CensorElement> { new CensorElement("table", true) }); // Hide the table element (case sensitive) in the request and response body
censors.CensorPathElementsByPatterns(new List<string> { ".*\\d{4}.*" }); // Hide any path element that contains 4 digits
var advancedOptions = new AdvancedOptions()
{
Censors = censors
};
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Record, advancedSettings);
Simulate a delay when replaying a recorded request, either using a specified delay or the original request duration.
NOTE: Delays may suffer from a small margin of error on certain .NET versions. Do not rely on the delay being exact down to the millisecond.
Default: No delay
using EasyVCR;
var cassette = new Cassette("path/to/cassettes", "my_cassette");
var advancedOptions = new AdvancedOptions()
{
SimulateDelay = true, // Simulate a delay of the original request duration when replaying (overrides ManualDelay)
ManualDelay = 1000 // Simulate a delay of 1000 milliseconds when replaying
};
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Replay, advancedSettings);
Set expiration dates for recorded requests, and decide what to do with expired recordings.
Default: No expiration
using EasyVCR;
var cassette = new Cassette("path/to/cassettes", "my_cassette");
var advancedOptions = new AdvancedOptions()
{
ValidTimeFrame = new TimeFrame() { // Any matching request is considered expired if it was recorded more than 30 days ago
Days = 30,
},
WhenExpired = ExpirationActions.ThrowException // Throw exception if the recording is expired
};
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Replay, advancedSettings);
Customize how a recorded request is determined to be a match to the current request.
Default: Method and full URL must match
using EasyVCR;
var cassette = new Cassette("path/to/cassettes", "my_cassette");
var advancedOptions = new AdvancedOptions()
{
MatchRules = new MatchRules().ByBody().ByHeader("X-My-Header"), // Match recorded requests by body and a specific header
};
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Replay, advancedSettings);
Customize how elements of a recorded request are organized in the cassette file. Helpful to avoid unnecessary git differences between cassette file versions.
Default: Elements are stored alphabetically
NOTE: This setting must be used when creating the cassette.
using EasyVCR;
var order = new CassetteOrder.None(); // elements of each request in a cassette won't be ordered in any particular way
var cassette = new Cassette("path/to/cassettes", "my_cassette", order);
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Replay, advancedSettings);
Have EasyVCR integrate with your custom logger to log warnings and errors.
Default: Logs to console
using EasyVCR;
var cassette = new Cassette("path/to/cassettes", "my_cassette");
var advancedOptions = new AdvancedOptions()
{
Logger = new MyCustomLogger(), // Have EasyVCR use your custom logger when making log entries
};
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Replay, advancedSettings);
Override how HttpClient request and response objects are converted into EasyVCR
request and response objects, and vice
versa.
Useful if HttpClient
suffers breaking changes in future .NET versions.
using EasyVCR;
var cassette = new Cassette("path/to/cassettes", "my_cassette");
var advancedOptions = new AdvancedOptions()
{
InteractionConverter = new MyInteractionConverter(), // use a custom interaction converter by implementing IInteractionConverter
};
var httpClient = HttpClients.NewHttpClient(cassette, Mode.Replay, advancedSettings);
In addition to individual recordable HttpClient instances, EasyVCR
also offers a built-in VCR, which can be used to
easily switch between multiple cassettes and/or modes. Any advanced settings applied to the VCR will be applied on every
request made using the VCR's HttpClient.
using EasyVCR;
var advancedSettings = new AdvancedSettings
{
Censors = new Censors().CensorQueryParametersByKeys(new List<string> { "api_key" }) // hide the api_key query parameter
};
// Create a VCR with the advanced settings applied
var vcr = new VCR(advancedSettings);
// Create a cassette and add it to the VCR
var cassette = new Cassette("path/to/cassettes", "my_cassette");
vcr.Insert(cassette);
// Set the VCR to record mode
vcr.Record();
// Get an HttpClient using the VCR
var httpClient = vcr.Client;
// Use the HttpClient as you would normally.
var response = await httpClient.GetAsync("https://google.com");
// Remove the cassette from the VCR
vcr.Eject();
- Scotch by Martin Leech, whose core functionality on which this is based.