I'm writing an http client for a service and for testing I want to use a net/http/httptest
server instead of calling out to the remote API. I can easily do this if I make the baseUrl
a global variable which gets set to the url of my test server. However, this makes the production code more fragile because baseUrl
can also be changed during runtime. My preference would be to make baseUrl
a const
for production code but still be able to change.
package main
const baseUrl = "http://google.com"
// in main_test.go
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
...
}
const baseUrl = ts.URL
// above line throws const baseUrl already defined error
Writing tests in Go requires a test file link, and this test file must always end with _test.go . By convention, Go testing files are always located in the same folder, or package, where the code they are testing resides.
In Go, const is a keyword introducing a name for a scalar value such as 2 or 3.14159 or "scrumptious" . Such values, named or otherwise, are called constants in Go. Constants can also be created by expressions built from constants, such as 2+3 or 2+3i or math. Pi/2 or ("go"+"pher") .
If your code uses a const value, it is not testing-friendly (regarding testing with different values of that parameter).
You could approach your problem with a slight refactoring. Let's say you have a function that uses this const:
const baseUrl = "http://google.com"
func MyFunc() string {
// use baseUrl
}
You could create another function that takes base URL as a parameter, and your original MyFunc()
calls this:
const baseUrl_ = "http://google.com"
func MyFunc() string {
// Call other function passing the const value
return myFuncImpl(baseUrl_)
}
func myFuncImpl(baseUrl string) string {
// use baseUrl
// Same implementation that was in your original MyFunc() function
}
This way the API of your library doesn't change, but now you can test the functionality of your original MyFunc()
by testing myFuncImpl()
, and you can pass any value to test with.
Calling MyFunc()
will remain safe as it always passes the const baseUrl_
to myFuncImpl()
where the implementation now resides. It's your decision whether you make this new myFuncImpl()
function exported or not; it may remain unexported as testing code may (should) be placed in the same package and can call it without problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With