testAccProvider is nil

In an acceptance test, I’m attempting make call to the provider’s API using this technique TestCase Reference API: Providers in the official documentation.

This provider is using terraform-plugin-sdk v2.7.0.

I’ve followed the example in that linked documentation, and the only difference in my implementation, is that init function, where the syntax to get a new provider has changed to New("dev")():

func init() {
	testAccProvider := New("dev")()
	testAccProviders = map[string]*schema.Provider{
		"example": testAccProvider,

The test runs normally, using the configured provider successfully, but when the test attempts to use testAccProvider in a Check function, it has become nil:

--- FAIL: TestAccResourceExampleMyResource (271.19s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x18dda96]

goroutine 40 [running]:
testing.tRunner.func1.2({0x19aa080, 0x2b29d20})
	/usr/local/go/src/testing/testing.go:1209 +0x24e
	/usr/local/go/src/testing/testing.go:1212 +0x218
panic({0x19aa080, 0x2b29d20})
	/usr/local/go/src/runtime/panic.go:1038 +0x215
	/Users/mars.hall/Projects/terraform-provider-example/internal/provider/resource_my_resource_test.go:51 +0x96

Has this changed with SDK v2? Any pointers to get this working?

Answering my own question :blush:

The testAccProvider/testAccProviders module variables are no longer used, apparently to avoid shared data between tests. So, none of the init() setup is required either.

Instead, in the tests, construct & configure a new provider each time it’s required:

provider := New("dev")()
diags := provider.Configure(context.Background(), terraform.NewResourceConfigRaw(nil))
if diags != nil {
	return false, fmt.Errorf("%+v", diags)
client := provider.Meta().(*exampleapi.Client)