go - Unable to mock due to error neither addressable nor a map index expression? - Stack Overflow

This is my 3 function, calling internally and depended,I want to write test caseI tried mock but but

This is my 3 function, calling internally and depended, I want to write test case I tried mock but but due to tightly coupled code CreateConnection and sendRequest unable to mock instead it calls actual function

func run(cmd *cobra.Command) error {
    response, err := getCurrentOrg()
    if err != nil {
        return fmt.Errorf("invalid input: %q", err)
    }
    acc := Account{}
    json.Unmarshal(response.Bytes(), &acc)
    printOrg(acc.Organization)
    return nil
}

func getCurrentOrg() (*sdk.Response, error) {
    // Create OCM client to talk
    ocmClient, err := utils.CreateConnection()
    if err != nil {
        return nil, err
    }
    defer func() {
        if err := ocmClient.Close(); err != nil {
            fmt.Printf("Cannot close the ocmClient (possible memory leak): %q", err)
        }
    }()
    return sendRequest(createGetCurrentOrgRequest(ocmClient))
}

func createGetCurrentOrgRequest(ocmClient *sdk.Connection) *sdk.Request {
    request := ocmClient.Get()
    err := arguments.ApplyPathArg(request, currentAccountApiPath)
    if err != nil {
        log.Fatalf("Can't parse API path '%s': %v\n", currentAccountApiPath, err)
    }

    return request
}

but unable to mock ocmClient, err := utils.CreateConnection() it gives error cannot assign to utils.CreateConnection (neither addressable nor a map index expression)

func TestOrgSuite(t *testing.T) {
    ginkgo.RunSpecs(t, "Org Suite")
}

var _ = ginkgo.Describe("getCurrentOrg", func() {
    var (
        apiServer      *ghttp.Server
        ocmClient      *sdk.Connection
        successResp    *Account
        successRespBytes []byte
    )

    // Setup runs before each test case to initialize the fake server and mock dependencies.
    ginkgo.BeforeEach(func() {
        var err error

        // Define a sample success response.
        successResp = &Account{
            Organization: Organization{
                ID:   "123",
                Name: "TestOrg",
            },
        }
        successRespBytes, err = json.Marshal(successResp)
        gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Failed to marshal success response")

        // Create a fake HTTP server.
        apiServer = ghttp.NewServer()

        // Mock utils.CreateConnection to return a connection to the fake server.
        originalCreateConnection := utils.CreateConnection
        utils.CreateConnection = func() (*sdk.Connection, error) {
            conn, err := sdk.NewConnectionBuilder().
                URL(apiServer.URL()).
                RetryLimit(0). // Disable retries for immediate failure detection
                Insecure(true). // Skip TLS for fake server
                Build()
            if err != nil {
                return nil, err
            }
            ocmClient = conn // Store for cleanup
            return conn, nil
        }
        ginkgo.DeferCleanup(func() {
            utils.CreateConnection = originalCreateConnection // Restore original function
            if ocmClient != nil {
                ocmClient.Close()
            }
            if apiServer != nil {
                apiServer.Close()
            }
        })
    })

    // Test scenarios for getCurrentOrg.
    ginkgo.Describe("fetching current anization", func() {
        ginkgo.It("succeeds with a valid 200 OK response", func() {
            // Configure the fake server to respond to the current account GET request.
            apiServer.AppendHandlers(
                ghttp.CombineHandlers(
                    ghttp.VerifyRequest(http.MethodGet, "/api/accounts_mgmt/v1/current_account"),
                    ghttp.RespondWith(
                        http.StatusOK,
                        successRespBytes,
                        http.Header{"Content-Type": []string{"application/json"}},
                    ),
                ),
            )

            // Call the function under test.
            resp, err := getCurrentOrg()

            // Verify the request succeeds and response matches expectations.
            gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Expected no error fetching current ")
            gomega.Expect(resp).ToNot(gomega.BeNil(), "Expected a non-nil response")
            gomega.Expect(resp.Status()).To(gomega.Equal(http.StatusOK), "Expected 200 OK status")

        })

    })
})

Reference : .go

This is my 3 function, calling internally and depended, I want to write test case I tried mock but but due to tightly coupled code CreateConnection and sendRequest unable to mock instead it calls actual function

func run(cmd *cobra.Command) error {
    response, err := getCurrentOrg()
    if err != nil {
        return fmt.Errorf("invalid input: %q", err)
    }
    acc := Account{}
    json.Unmarshal(response.Bytes(), &acc)
    printOrg(acc.Organization)
    return nil
}

func getCurrentOrg() (*sdk.Response, error) {
    // Create OCM client to talk
    ocmClient, err := utils.CreateConnection()
    if err != nil {
        return nil, err
    }
    defer func() {
        if err := ocmClient.Close(); err != nil {
            fmt.Printf("Cannot close the ocmClient (possible memory leak): %q", err)
        }
    }()
    return sendRequest(createGetCurrentOrgRequest(ocmClient))
}

func createGetCurrentOrgRequest(ocmClient *sdk.Connection) *sdk.Request {
    request := ocmClient.Get()
    err := arguments.ApplyPathArg(request, currentAccountApiPath)
    if err != nil {
        log.Fatalf("Can't parse API path '%s': %v\n", currentAccountApiPath, err)
    }

    return request
}

but unable to mock ocmClient, err := utils.CreateConnection() it gives error cannot assign to utils.CreateConnection (neither addressable nor a map index expression)

func TestOrgSuite(t *testing.T) {
    ginkgo.RunSpecs(t, "Org Suite")
}

var _ = ginkgo.Describe("getCurrentOrg", func() {
    var (
        apiServer      *ghttp.Server
        ocmClient      *sdk.Connection
        successResp    *Account
        successRespBytes []byte
    )

    // Setup runs before each test case to initialize the fake server and mock dependencies.
    ginkgo.BeforeEach(func() {
        var err error

        // Define a sample success response.
        successResp = &Account{
            Organization: Organization{
                ID:   "123",
                Name: "TestOrg",
            },
        }
        successRespBytes, err = json.Marshal(successResp)
        gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Failed to marshal success response")

        // Create a fake HTTP server.
        apiServer = ghttp.NewServer()

        // Mock utils.CreateConnection to return a connection to the fake server.
        originalCreateConnection := utils.CreateConnection
        utils.CreateConnection = func() (*sdk.Connection, error) {
            conn, err := sdk.NewConnectionBuilder().
                URL(apiServer.URL()).
                RetryLimit(0). // Disable retries for immediate failure detection
                Insecure(true). // Skip TLS for fake server
                Build()
            if err != nil {
                return nil, err
            }
            ocmClient = conn // Store for cleanup
            return conn, nil
        }
        ginkgo.DeferCleanup(func() {
            utils.CreateConnection = originalCreateConnection // Restore original function
            if ocmClient != nil {
                ocmClient.Close()
            }
            if apiServer != nil {
                apiServer.Close()
            }
        })
    })

    // Test scenarios for getCurrentOrg.
    ginkgo.Describe("fetching current anization", func() {
        ginkgo.It("succeeds with a valid 200 OK response", func() {
            // Configure the fake server to respond to the current account GET request.
            apiServer.AppendHandlers(
                ghttp.CombineHandlers(
                    ghttp.VerifyRequest(http.MethodGet, "/api/accounts_mgmt/v1/current_account"),
                    ghttp.RespondWith(
                        http.StatusOK,
                        successRespBytes,
                        http.Header{"Content-Type": []string{"application/json"}},
                    ),
                ),
            )

            // Call the function under test.
            resp, err := getCurrentOrg()

            // Verify the request succeeds and response matches expectations.
            gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Expected no error fetching current ")
            gomega.Expect(resp).ToNot(gomega.BeNil(), "Expected a non-nil response")
            gomega.Expect(resp.Status()).To(gomega.Equal(http.StatusOK), "Expected 200 OK status")

        })

    })
})

Reference : https://github/openshift/osdctl/blob/master/cmd//current.go

Share Improve this question edited Mar 3 at 11:39 Aupa asked Mar 3 at 11:18 AupaAupa 3851 gold badge3 silver badges15 bronze badges 8
  • 1 What is your question? Please be specific! – Ulrich Eckhardt Commented Mar 3 at 11:38
  • unable to mock ocmClient, err := utils.CreateConnection() it gives error cannot assign to utils.CreateConnection (neither addressable nor a map index expression) – Aupa Commented Mar 3 at 11:40
  • 3 That is not a question, it's just an error message. Also, are you sure that you don't mix up the two places in the code? – Ulrich Eckhardt Commented Mar 3 at 11:43
  • 1 Please: Stop that mocking business. Mocking is not the main and best technique to write tests in Go (it might be in other languages, but NOT in Go). – Volker Commented Mar 3 at 11:45
  • 1 utils.CreateConnection is a package function, you cannot assign to that. There is no suggestion to fix the error, because what you're trying to do is not valid. – Mr_Pink Commented Mar 3 at 13:24
 |  Show 3 more comments

1 Answer 1

Reset to default 1

utils.CreateConnection is an identifier bound to a function declaration, so it's not assignable.

If you want to reassign it, you have to assign it to a variable first:

import (
    sdk "github/openshift-online/ocm-sdk-go"
    "github/openshift/osdctl/pkg/utils"
)

// ...
    createConnection := utils.CreateConnection
    ocmClient, err := createConnection()
    // ...

    createConnection = func() (*sdk.Connection, error) {
        return ..., nil
    }
    ocmClient, err = createConnection()
    // ...

What you are trying to do would work in JavaScript for an “util” object, but util is no object (it is a PackageName used in qualified identifiers) and Go is not a prototype-based language.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745097280a4611055.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信