Skip to content

Commit ee23b9f

Browse files
authored
Add PostApplyFunc to plan/apply testing (#566)
* Add `PostApplyFunc` to plan/apply testing * Adjust wording * Add changelog entry
1 parent 7ed2ee2 commit ee23b9f

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
kind: ENHANCEMENTS
2+
body: 'helper/resource: Adds `PostApplyFunc` test step hook to run generic post-apply logic for plan/apply testing.'
3+
time: 2025-10-14T16:26:59.267372-04:00
4+
custom:
5+
Issue: "566"

helper/resource/testing.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,10 @@ type TestStep struct {
671671
// SkipFunc is called after PreConfig but before applying the Config.
672672
SkipFunc func() (bool, error)
673673

674+
// PostApplyFunc is called after the Config is applied and after all plan/apply checks are run.
675+
// This can be used to perform assertions against API values that are not stored in Terraform state.
676+
PostApplyFunc func()
677+
674678
//---------------------------------------------------------------
675679
// ImportState testing
676680
//---------------------------------------------------------------

helper/resource/testing_new_config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,12 @@ func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugint
451451
}
452452
}
453453

454+
if step.PostApplyFunc != nil {
455+
logging.HelperResourceDebug(ctx, "Calling TestCase PostApplyFunc")
456+
step.PostApplyFunc()
457+
logging.HelperResourceDebug(ctx, "Called TestCase PostApplyFunc")
458+
}
459+
454460
if refreshAfterApply && !step.Destroy && !step.PlanOnly {
455461
if len(c.Steps) > stepIndex+1 {
456462
// If the next step is a refresh, then we have no need to refresh here

helper/resource/testing_new_config_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,3 +842,67 @@ func Test_ConfigStateChecks_Errors(t *testing.T) {
842842
},
843843
})
844844
}
845+
846+
func Test_PostApplyFunc_Called(t *testing.T) {
847+
t.Parallel()
848+
849+
spy1 := &stateCheckSpy{}
850+
postFuncCalled := false
851+
UnitTest(t, TestCase{
852+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
853+
tfversion.SkipBelow(tfversion.Version1_0_0), // ProtoV6ProviderFactories
854+
},
855+
ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){
856+
"test": providerserver.NewProviderServer(testprovider.Provider{
857+
Resources: map[string]testprovider.Resource{
858+
"test_resource": {
859+
CreateResponse: &resource.CreateResponse{
860+
NewState: tftypes.NewValue(
861+
tftypes.Object{
862+
AttributeTypes: map[string]tftypes.Type{
863+
"id": tftypes.String,
864+
},
865+
},
866+
map[string]tftypes.Value{
867+
"id": tftypes.NewValue(tftypes.String, "test"),
868+
},
869+
),
870+
},
871+
SchemaResponse: &resource.SchemaResponse{
872+
Schema: &tfprotov6.Schema{
873+
Block: &tfprotov6.SchemaBlock{
874+
Attributes: []*tfprotov6.SchemaAttribute{
875+
{
876+
Name: "id",
877+
Type: tftypes.String,
878+
Computed: true,
879+
},
880+
},
881+
},
882+
},
883+
},
884+
},
885+
},
886+
}),
887+
},
888+
Steps: []TestStep{
889+
{
890+
Config: `resource "test_resource" "test" {}`,
891+
ConfigStateChecks: []statecheck.StateCheck{
892+
spy1,
893+
},
894+
PostApplyFunc: func() {
895+
postFuncCalled = true
896+
},
897+
},
898+
},
899+
})
900+
901+
if !postFuncCalled {
902+
t.Error("expected PostApplyFunc to be called at least once")
903+
}
904+
905+
if !spy1.called {
906+
t.Error("expected ConfigStateChecks spy1 to be called at least once")
907+
}
908+
}

0 commit comments

Comments
 (0)