Search code examples
unit-testinggostructdtogo-gorm

How to pass an array of structs inside a struct?


I'm passing array of structs inside a struct, in unit testing, i have used a dto of ServiceAccounts and my testing code TestStoreServiceAccounts.How to pass an array of structs inside a struct?Nesting of structs is what i'm failing to understand.

func TestStoreServiceAccounts(t *testing.T) {
StoreServiceAccounts = func(serviceAccounts []models.ServiceAccount) ([]string, error) {
    ServiceAccounts := []string{"service-account-details-inserted"}
    return ServiceAccounts, nil
}
Data := dto.ServiceAccountRequestDTO{
    ServiceAccounts : []{ //error on this line
        WorkspaceID:        1,
        ServiceAccountName: "sa-10",
        ServiceAccountKey: dto.ServiceAccountKey{
            Type:                    "service_account",
            ProjectID:               "abc",
            PrivateKeyID:            "123",
            PrivateKey:              "234",
            ClientEmail:             "read-clusters",
            ClientID:                "cdf",
            AuthURI:                 "https://accounts.google.com/o/oaut",
            TokenURI:                "https://oauth2.googleapis.com/token",
            AuthProviderX509CertURL: "https://www.googleapis.com",
            ClientX509CertURL:       "xwy",
        },
        CreatedAt: "2021-03-08 17:05:21.0",
        UpdatedAt: "2021-03-08 17:05:21.0",
        CreatedBy: "user-01",
        UpdatedBy: "user-01",
    },
}

responseData, err := clusterService.StoreServiceAccountsService(context.Background(), Data)
serviceAccountsdata := []string{"service-account-details-inserted"}

assert.Nil(t, err)
assert.NotNil(t, responseData)
assert.EqualValues(t, serviceAccountsdata, responseData)

}

    // ServiceAccountRequestDTO - DTO of service account model
type ServiceAccountRequestDTO struct {
    ServiceAccounts []struct {
        WorkspaceID        int64             `json:"workspace_id"`
        ServiceAccountName string            `json:"serviceAccountName"`
        ServiceAccountKey  ServiceAccountKey `json:"serviceAccountKey"`
        CreatedAt          string            `json:"created_at"`
        UpdatedAt          string            `json:"updated_at"`
        CreatedBy          string            `json:"created_by"`
        UpdatedBy          string            `json:"updated_by"`
    } `json:"serviceAccounts"`
}```

Solution

  • TL;DR: define your ServiceAccount struct outside the DTO struct so you can reuse it.

    Since you are defining the structure of ServiceAccounts inside the ServiceAccountRequestDTO struct, you will also again need to define it when you are creating the object, like so:

    Data := dto.ServiceAccountRequestDTO{
        ServiceAccounts : []struct{
            WorkspaceID        int64             `json:"workspace_id"`
            ServiceAccountName string            `json:"serviceAccountName"`
            ServiceAccountKey  ServiceAccountKey `json:"serviceAccountKey"`
            CreatedAt          string            `json:"created_at"`
            UpdatedAt          string            `json:"updated_at"`
            CreatedBy          string            `json:"created_by"`
            UpdatedBy          string            `json:"updated_by"`
        } `json:"serviceAccounts"`{ //start of slice (it's technically not an array) of objects
            { // first object
              WorkspaceID:        1,
              ServiceAccountName: "sa-10",
              ServiceAccountKey: dto.ServiceAccountKey{
                  Type:                    "service_account",
                  ProjectID:               "abc",
                  PrivateKeyID:            "123",
                  PrivateKey:              "234",
                  ClientEmail:             "read-clusters",
                  ClientID:                "cdf",
                  AuthURI:                 "https://accounts.google.com/o/oaut",
                  TokenURI:                "https://oauth2.googleapis.com/token",
                  AuthProviderX509CertURL: "https://www.googleapis.com",
                  ClientX509CertURL:       "xwy",
              },
              CreatedAt: "2021-03-08 17:05:21.0",
              UpdatedAt: "2021-03-08 17:05:21.0",
              CreatedBy: "user-01",
              UpdatedBy: "user-01",
            },
            // .. more ServiceAccount objects ...
        },
    }
    

    Now this is of course incredibly painful to write and read and duplicated a lot of code. So instead you should define the structure outside

    
    type ServiceAccount struct{
            WorkspaceID        int64             `json:"workspace_id"`
            ServiceAccountName string            `json:"serviceAccountName"`
            ServiceAccountKey  ServiceAccountKey `json:"serviceAccountKey"`
            CreatedAt          string            `json:"created_at"`
            UpdatedAt          string            `json:"updated_at"`
            CreatedBy          string            `json:"created_by"`
            UpdatedBy          string            `json:"updated_by"`
        } `json:"serviceAccounts"`
    }
    
    type ServiceAccountRequestDTO struct {
        ServiceAccounts []ServiceAccount
    }
    
    

    and then you can create your DTO like this

    Data := dto.ServiceAccountRequestDTO{
        ServiceAccounts : []ServiceAccount{ //start of slice of objects
            ServiceAccount { // first object
              WorkspaceID:        1,
              ServiceAccountName: "sa-10",
              ServiceAccountKey: dto.ServiceAccountKey{
                  Type:                    "service_account",
                  ProjectID:               "abc",
                  PrivateKeyID:            "123",
                  PrivateKey:              "234",
                  ClientEmail:             "read-clusters",
                  ClientID:                "cdf",
                  AuthURI:                 "https://accounts.google.com/o/oaut",
                  TokenURI:                "https://oauth2.googleapis.com/token",
                  AuthProviderX509CertURL: "https://www.googleapis.com",
                  ClientX509CertURL:       "xwy",
              },
              CreatedAt: "2021-03-08 17:05:21.0",
              UpdatedAt: "2021-03-08 17:05:21.0",
              CreatedBy: "user-01",
              UpdatedBy: "user-01",
            },
            // .. more ServiceAccount objects ...
        },
    }