Advice on how to insert a mock client to an external API

Hi,

I am want to write tests for the provider that I created. When reading the documentation and the scaffold code for a provider, I understand that for testing it is assumed that a real backend/external API should be used.

On the one end I understand that this will give good and reliable results. However, I am more inclined to mock those external APIs. I think it should be possible but it does not look straightforward to me yet. I spent quite some time reading the source code but I came to a point that I would rather ask then going over more lines of source code, verious provider api’s, versions etc.

I am using terraform-plugin-framework as recommended for new plugins.
The provider is initialized with an API key for the backend service. In the provider’s configure method, a client object that has access to the backend is sent in the provider.ConfigureResponse in the DataResourceData and ResourceData properties.

The resources read the provider data when their Configure method is called and the the Read/Delete/Update etc methods can then acccess the external resources.

I set this up following the various comments section in the scaffolding repo. This was very useful and I got it up and running quite fast.

For testing I want to mock the client that has access to the external API. I would think that I should get my mock client injected in the provider in some way. Where do I do that?

I have see that the TestCase object has a property called
ProviderFactories map[string]func() (*schema.Provider, error)

Of course I can add a constructor function in here, I cannot find how to populate any ResourceData or DataResourceData objects.
Is the idea that this should be done in through the ConfigureContextFunc property of schema.Provider?
The type definition is
type ConfigureContextFunc func(context.Context, *ResourceData) (interface{}, diag.Diagnostics)

So should I change *ResourceData here and assume that resources will pick up this object when they get configured?
if so then that would be nice to know. But How can I do the same thing for injecting DataResourceData?

If I am completely on the wrong track, I would welcome you gives some guidelines how to inject the mock client object.

I was able to find away after being AFK for a while.

I used the ProtoV6ProviderFactories to do the trick after I noticed that this was used the link the provider to the testcase.

It resulted in quite some ugly code, but … it works.
I want to share how I made it work but i have some time pressure to finish some things first and I want to present a bit more cleaner code than I have now.

I have the same issue, I wonder if there is some neat way to do it? Or some official way ?
If there isnt any response from the terraform team then I guess it will just be submitted as is.

on the scaffolding framework repo it says:

Note: Acceptance tests create real resources, and often cost money to run.

Is that the case ? Would we need to provide an API key to run things for real ?

would love to see any examples you ended up with

we use httpmock jarcoal/httpmock: HTTP mocking for Golang (github.com) to mock the rest apis that our provider uses. This lets us unit test all the code behind a resource or data source. We can inject failures and ensure we have proper error handling. For acceptance testing, we create real resources and call the real APIs

terraform-provider-power-platform/internal/powerplatform/datasource_environments_test.go at main · microsoft/terraform-provider-power-platform (github.com)