简体   繁体   中英

How to mock Terraform functions

I'm studying Terraform and as a test lover I'm using Terratest to test it out but, I'm not being able to mock Terraform's functions such as timestamp() . Tried some stuffs such as use the library monkey for mocking but so far, none of my approches worked.

Does anyone have an idea about how to mock terraform's functions for testing proposals?

Here a small example that can exemplify my question:

file: main.tf

locals {
  creation_time = formatdate("YYYYMMDDhhmmss", timestamp())
}

file: outputs.tf

output "CreationDate" {
  value = local.creation_time,
  description = "Bla bla bla"
}

./tests/main_test.go

package study

import (
  "testing"
  "github.com/stretchr/testify/assert"
  "github.com/stretchr/terratest/modules/terraform"
  "bou.ke/monkey"
)

func Test(t * testing.T) {
  t.Parallel()

  terraformOptions := &terraform.Options{
    TerraformDir" "../",
  }

  monkey.Patch(time.Now, func() time.Time {
    return time.Date(2022, 12, 8, 23, 59, 1, time.UTC)
  })

  defer terraform.Destroy(t, terraformOptions)
  terraform.InitAndApply(t, terraformOptions)

  output = terraform.Output(t, terraformOptions, "CreationDate")
  assert.Equal(t, "20221208235901", output)
}

Super simplified example about how to run it:

go mod init study
go mod tidy
cd tests
go test

So, I'm expecting to mock a function from Terraform and assert this value to make sure terraform's file/module does what's expected.

Unlike some other languages, the Terraform language does not support this sort "monkey patch"-style mocking where you unilaterally change the definition of something for the entire program.

Terraform modules can their behavior only based on input variables and provider behaviors, so you can add optional features to your module to make it explicitly configurable, if you wish:

variable "override_timestamp" {
  type    = string
  default = null
}

locals {
  creation_time = coalesce(var.override_timestamp, timestamp())
}

Of course, this technique will not test that your module is actually calling timestamp in the normal case, so it's questionable whether this would actually be useful for testing.

It might be more profitable to instead design your test driver to verify that the timestamp has overall correct syntax and then do some fuzzy matching on it, such as asserting that the reported instant is greater than or equal to the test start time and less than or equal to the test end time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM