Injecting client in my handler function

I am testing scenario where I want to inject a client in my “CreateEmployee” function, only for my test case and not in prod/stage

My handler func looks like…

	// to create a employee in the system

	func CreateEmployee(w http.ResponseWriter, r *http.Request) {
		/// some code here, mapping json from request body to http request...etc		

		response, e := client.Do(request)  // this is http.Client
	}

I am writing a test case that looks like

func TestCreateEmployee(t *testing.T) {


	var jsonStr = []byte(`{employee details as json}`)

	req, err := http.NewRequest("POST", "http://www.exapmle.com/empsys/", bytes.NewBuffer(jsonStr))
	
	resp := httptest.NewRecorder()

	CreateEmployee(resp,req) // I am calling my function here, but not sure how client.Do will behave.. 
	/// and further code
}

can anybody suggest a good way to test this scenario

What is the request that client is executing?

This looks like an integration test since it depends on a third system, the host that client connects to. Is this host always available?

Do you you want the code that is hidden behind this comment?

// some code here, mapping json from request body to http request...etc

the request is for e.g. creating a keycloak user and keycloak is not available all the time.

when i call “client.Do(request)”… it create the user and return some response

I don’t need the code… but always getting errors when I call “client.Do(request)” so want to mock the Do method

Then you will have to catch this when you call client.Do. But since success of failure is not in your hands, your test will not be deterministic. This is not a good idea.

What should I do…I have no idea. Can I hardcode some response… or should I change my current code, to make it testable

What are you trying to do? Testing code that depends on a third party service is not a good idea.

You could write a stub server for the third party service: Figure out the relevant parts of the HTTP API it provides and that you call will client.Do. Implement a HTTP service that stubs these parts of the API and that returns well defined data depending on known requests. Then write tests that make client.Do call the stub with these requests and test that the response is handled correctly by your code.

Will the stub look like

func main() {
mock := &ClientMock{}
err := TestMyClient(mock)
if err != nil {
fmt.Println(err.Error())
}
}

type HttpClient interface {
Do(req *http.Request) (*http.Response, error)
}

func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
return &http.Response{}, nil
}

type ClientMock struct {
}

I would not return nothing for a call to Do.

Again, what are you trying to test? What is CreateEmployee doing? There must be more in this function than just the request to the remote server. Your test code would test that, given a well defined request, this HTTP handler works correctly. What is it that CreateEmployee does before and after the remote call? That is what you want to test. The stub would help you to make the remote call work consistently.

I think this stub idea can work for me… I will try that… do you know any online example for stub

I this function i marshal and unmarshal json object (received as request body) and forward request to third party

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.