I have to write test case for below function
func sendRequest(request *sdk.Request) (*sdk.Response, error) {
response, err := request.Send()
if err != nil {
return nil, fmt.Errorf("cannot send request: %q", err)
}
return response, nil
}
I am trying to mock send() but *sdk.Request and *sdk.Response has unexported properties as below
type Request struct {
transport http.RoundTripper
method string
path string
query url.Values
header http.Header
body []byte
}
type Response struct {
status int
header http.Header
body []byte
}
This is my test case
// Helper function to create a mock response
func createMockResponses(status string) *sdk.Response {
response := &sdk.Response{}
// Use reflection or public methods to set fields if available
response.Status() // Assuming SetStatus is a public method
return response
}
// Test cases
func TestSendRequest_Successs(t *testing.T) {
// Create a properly initialized sdk.Request object
request := &sdk.Request{
}
// Patch the Send method to return a mock response
defer monkey.UnpatchAll() // Ensure the patch is removed after the test
monkey.PatchInstanceMethod(
reflect.TypeOf(request),
"Send",
func(*sdk.Request) (*sdk.Response, error) {
return createMockResponses("OK"), nil
},
)
// Call the function under test
response, err := sendRequest(request)
// Assertions
assert.NoError(t, err)
assert.Equal(t, "OK", response.Status()) // Assuming GetStatus is a public method
}
But getting error
cannot refer to unexported field transport in struct literal of type sdk.Request
and inside send function there is method below where it enters into error and gives error
response, err := r.transport.RoundTrip(request)
if err != nil {
return
}
Error
--- FAIL: TestSendRequest_Successs (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x491ad80]
goroutine 25 [running]:
testing.tRunner.func1.2({0x4e8e560, 0x7690490})
/usr/local/go/src/testing/testing.go:1632 +0x230
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1635 +0x35e
panic({0x4e8e560?, 0x7690490?})
/usr/local/go/src/runtime/panic.go:785 +0x132
github/openshift-online/ocm-sdk-go.(*Request).SendContext(0xc0001dff00, {0x5a27bd0, 0x7896960})
/home/amiupadh/go/pkg/mod/github/openshift-online/[email protected]/request.go:122 +0x5c0
github/openshift-online/ocm-sdk-go.(*Request).Send(...)
/home/amiupadh/go/pkg/mod/github/openshift-online/[email protected]/request.go:95
github/openshift/osdctl/cmd/.sendRequest(0x5a44750?)
/home/amiupadh/go/src/osdctl/cmd//common.go:42 +0x25
github/openshift/osdctl/cmd/.TestSendRequest_Successs(0xc00079a820)
/home/amiupadh/go/src/osdctl/cmd//common_test.go:365 +0xc5
testing.tRunner(0xc00079a820, 0x5563370)
/usr/local/go/src/testing/testing.go:1690 +0xf4
created by testing.(*T).Run in goroutine 1
/usr/local/go/src/testing/testing.go:1743 +0x390
FAIL github/openshift/osdctl/cmd/ 0.019s
Reference : .go
I have to write test case for below function
func sendRequest(request *sdk.Request) (*sdk.Response, error) {
response, err := request.Send()
if err != nil {
return nil, fmt.Errorf("cannot send request: %q", err)
}
return response, nil
}
I am trying to mock send() but *sdk.Request and *sdk.Response has unexported properties as below
type Request struct {
transport http.RoundTripper
method string
path string
query url.Values
header http.Header
body []byte
}
type Response struct {
status int
header http.Header
body []byte
}
This is my test case
// Helper function to create a mock response
func createMockResponses(status string) *sdk.Response {
response := &sdk.Response{}
// Use reflection or public methods to set fields if available
response.Status() // Assuming SetStatus is a public method
return response
}
// Test cases
func TestSendRequest_Successs(t *testing.T) {
// Create a properly initialized sdk.Request object
request := &sdk.Request{
}
// Patch the Send method to return a mock response
defer monkey.UnpatchAll() // Ensure the patch is removed after the test
monkey.PatchInstanceMethod(
reflect.TypeOf(request),
"Send",
func(*sdk.Request) (*sdk.Response, error) {
return createMockResponses("OK"), nil
},
)
// Call the function under test
response, err := sendRequest(request)
// Assertions
assert.NoError(t, err)
assert.Equal(t, "OK", response.Status()) // Assuming GetStatus is a public method
}
But getting error
cannot refer to unexported field transport in struct literal of type sdk.Request
and inside send function there is method below where it enters into error and gives error
response, err := r.transport.RoundTrip(request)
if err != nil {
return
}
Error
--- FAIL: TestSendRequest_Successs (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x491ad80]
goroutine 25 [running]:
testing.tRunner.func1.2({0x4e8e560, 0x7690490})
/usr/local/go/src/testing/testing.go:1632 +0x230
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1635 +0x35e
panic({0x4e8e560?, 0x7690490?})
/usr/local/go/src/runtime/panic.go:785 +0x132
github/openshift-online/ocm-sdk-go.(*Request).SendContext(0xc0001dff00, {0x5a27bd0, 0x7896960})
/home/amiupadh/go/pkg/mod/github/openshift-online/[email protected]/request.go:122 +0x5c0
github/openshift-online/ocm-sdk-go.(*Request).Send(...)
/home/amiupadh/go/pkg/mod/github/openshift-online/[email protected]/request.go:95
github/openshift/osdctl/cmd/.sendRequest(0x5a44750?)
/home/amiupadh/go/src/osdctl/cmd//common.go:42 +0x25
github/openshift/osdctl/cmd/.TestSendRequest_Successs(0xc00079a820)
/home/amiupadh/go/src/osdctl/cmd//common_test.go:365 +0xc5
testing.tRunner(0xc00079a820, 0x5563370)
/usr/local/go/src/testing/testing.go:1690 +0xf4
created by testing.(*T).Run in goroutine 1
/usr/local/go/src/testing/testing.go:1743 +0x390
FAIL github/openshift/osdctl/cmd/ 0.019s
Reference : https://github/openshift/osdctl/blob/master/cmd//common.go
as we have non exported members for Request and Response structs, we better use methods provided by library to write tests related to them instead of replacing their pointer receiver methods using monkey library, by the way I think your send method is a wrapper to Request.Send() and thus writing test for such wrapper is not necessary and actual send method should write related test I suggest to think more about the aim of your test by asking yourself: are we going to test our send method with all possible inputs(actually nil or not nil are sufficient tests here) or we're going to test Send method of sdk? , any way here is working test:
package
import (
"encoding/json"
"net/http"
"testing"
"github/onsi/ginkgo/v2/dsl/core" // nolint
"github/onsi/gomega" // nolint
"github/onsi/gomega/ghttp"
sdk "github/openshift-online/ocm-sdk-go"
"github/openshift-online/ocm-sdk-go/logging"
. "github/openshift-online/ocm-sdk-go/testing" // nolint
)
var OkResp = Resp{"OK"}
type Resp struct {
Result string `json:"result"`
}
// Test cases
func TestSendRequest(t *testing.T) {
var apiServer *ghttp.Server
var connection *sdk.Connection
var logger logging.Logger
var okRespBytes []byte
core.BeforeEach(func() {
var err error
okRespBytes, err = json.Marshal(OkResp)
gomega.Expect(err).ToNot(gomega.HaveOccurred())
// Create the API server:
apiServer = MakeTCPServer()
// Create the connection:
connection, err = sdk.NewConnectionBuilder().
Logger(logger).
URL(apiServer.URL()).
RetryLimit(0).
Build()
gomega.Expect(err).ToNot(gomega.HaveOccurred())
})
core.Describe("Get", func() {
core.It("Sends path", func() {
// Configure the server:
apiServer.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest(http.MethodGet, "/mypath"),
RespondWithJSON(http.StatusOK, string(okRespBytes)),
),
)
// Build the request:
request := connection.Get().
Path("/mypath")
// Send the request:
resp, err := sendRequest(request)
gomega.Expect(err).ToNot(gomega.HaveOccurred())
gomega.Expect(resp).Should(gomega.MatchJSON(OkResp))
})
})
}