dnaeon / go-vcr

Record and replay your HTTP interactions for fast, deterministic and accurate tests

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support read-modify-reread interactions

mtrmac opened this issue · comments

Currently, recorder.requestHandler, via Cassette.GetInteraction, always returns the first matching interaction.

This does not work when the client first reads original state, then updates it, and then re-reads the modified state, with both reads using the same URL. That interaction is recorded correctly (Cassette.AddInteraction simply appends without checking for duplicates), but the replay always returns the first read, i.e. the modified state is not visible.

A possible, somewhat hacky, fix, could be for the Recorder to keep an index of last used interaction, and for Cassette to start searching from that index+1, possibly wrapping over.

Alternatively, the replay could be made “strict” in the sense that only exactly the same sequence of http.Requests in that exact order would be available during the replay, and any reordered use would result in ErrInteractionNotFound or similar.

A bit of a hack, but I worked around this issue by maintaining a counter and modifying each outgoing URL with its value as a dummy parameter:

type incrementingTransport struct {
	Transport http.RoundTripper
	counter   int
}

func (it *incrementingTransport) RoundTrip(r *http.Request) (*http.Response, error) {
	values := r.URL.Query()
	values.Add("_inc", strconv.Itoa(it.counter))

	r.URL.RawQuery = values.Encode()
	it.counter += 1
	return it.Transport.RoundTrip(r)
}
http.DefaultTransport = &incrementingTransport{Transport: vcrRecorder.Transport}

This was fixed by #37.