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

go-vcr does not work with `google/go-github` and/or `golang.org/x/oauth2` library

AnalogJ opened this issue · comments

I'm attempting to record and playback interactions with the Github API (using the google/go-github library). However my interactions are not being recorded to cassettes. The "same" code is tested and working with other libraries, so I'm not sure what's going on.
For additional context, I had previously used the https://github.com/seborama/govcr library, and it was able to record the interactions correctly (though I removed it because it seems to be unmaintained).

Here's a simplified version of my test suite. It passes, but does not create any recordings. If I had to guess, there's some internal magic in the oauth2.Transport that go-vcr can't hook into.

package example_test

import (
	"context"
	"github.com/dnaeon/go-vcr/cassette"
	"github.com/dnaeon/go-vcr/recorder"
	"github.com/google/go-github/v33/github"
	"github.com/stretchr/testify/require"
	"golang.org/x/oauth2"
	"net/http"
	"path"
	"testing"
)

func TestGithub(t *testing.T) {
	//custom http.Transport, since github uses oauth2 authentication
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: "YOUR_GITHUB_TOKEN"},
	)

	tr := &oauth2.Transport{
		Base:  http.DefaultTransport,
		Source: oauth2.ReuseTokenSource(nil, ts),
	}

	// Start our recorder
	vcrRecorder, err := recorder.NewAsMode(path.Join("testdata", "fixtures", t.Name()), recorder.ModeRecording, tr)
	require.NoError(t, err)


	// Filter out dynamic & sensitive data/headers
	// Your test code will continue to see the real access token and
	// it is redacted before the recorded interactions are saved
        // =====> commenting out this section has no impact on missing recording
	vcrRecorder.AddSaveFilter(func(i *cassette.Interaction) error {
		delete(i.Request.Headers, "Authorization")
		delete(i.Request.Headers, "User-Agent")
		i.Request.Headers["Authorization"] = []string{"Basic UExBQ0VIT0xERVI6UExBQ0VIT0xERVI="} //PLACEHOLDER:PLACEHOLDER

		return nil
	})

        // custom http.client
	httpClient := &http.Client{
		Transport: vcrRecorder,
	}

	ghClient := github.NewClient(httpClient)

	// =====> actual test, should create cassettes, but does not.
	_, _, err = ghClient.Users.Get(context.Background(), "")

	require.NoError(t, err)
}

Hey @AnalogJ ,

I don't see in your example code a call to vcrRecorder.Stop().

Once you are done with the recording you should explicitly call vcrRecorder.Stop(), which is when saving of the cassettes happens.

Can you try this code?

package example_test

import (
	"context"
	"github.com/dnaeon/go-vcr/cassette"
	"github.com/dnaeon/go-vcr/recorder"
	"github.com/google/go-github/v33/github"
	"github.com/stretchr/testify/require"
	"golang.org/x/oauth2"
	"net/http"
	"path"
	"testing"
)

func TestGithub(t *testing.T) {
	//custom http.Transport, since github uses oauth2 authentication
	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: "YOUR_GITHUB_TOKEN"},
	)

	tr := &oauth2.Transport{
		Base:  http.DefaultTransport,
		Source: oauth2.ReuseTokenSource(nil, ts),
	}

	// Start our recorder
	vcrRecorder, err := recorder.NewAsMode(path.Join("testdata", "fixtures", t.Name()), recorder.ModeRecording, tr)
	require.NoError(t, err)
        defer vcrRecorder.Stop() // NEWLY ADDED CODE HERE


	// Filter out dynamic & sensitive data/headers
	// Your test code will continue to see the real access token and
	// it is redacted before the recorded interactions are saved
        // =====> commenting out this section has no impact on missing recording
	vcrRecorder.AddSaveFilter(func(i *cassette.Interaction) error {
		delete(i.Request.Headers, "Authorization")
		delete(i.Request.Headers, "User-Agent")
		i.Request.Headers["Authorization"] = []string{"Basic UExBQ0VIT0xERVI6UExBQ0VIT0xERVI="} //PLACEHOLDER:PLACEHOLDER

		return nil
	})

        // custom http.client
	httpClient := &http.Client{
		Transport: vcrRecorder,
	}

	ghClient := github.NewClient(httpClient)

	// =====> actual test, should create cassettes, but does not.
	_, _, err = ghClient.Users.Get(context.Background(), "")

	require.NoError(t, err)
}

🤦 I had that in the teardown function of test suites testing other libraries, but I missed it for github. Adding it fixed the issue, closing.

Thanks for your help @dnaeon !