Question description
Hi there, thank you for the awesome Gofiber package. I have a question about testing Gofiber as a proxy. Small caveat: I am somewhat new to Go and Gofiber.
I have implemented a small proxy service using Gofiber, and I used your tests here as reference for writing my own tests.
I'd like to know if this the recommend or correct approach to testing Gofiber as a proxy? Or if I should be mocking out the proxying somehow.
Handler Function
func BulkEventsHandler(c *fiber.Ctx) error {
url := buildURL(cfg().Proxy.Forward.Events, c.Path())
// Before we do the proxy save the body to a DB
// in a goroutine so that it doesn't block
go saveEvent(copyBody(c.Request().Body()))
if err := proxy.Do(c, url); err != nil {
logrus.Error("Proxy to Foo failed: ", err)
return err
}
// Remove Server header from response
c.Response().Header.Del(fiber.HeaderServer)
return nil
}
TestFunction
func TestBulkEventsHandler(t *testing.T) {
// Parallel signals that this test is to be run in parallel
// with (and only with) other parallel tests.
t.Parallel()
// Create a new fiber app
app := fiber.New()
// Make sure the proxy middleware doesn't have problems with
// self-signed certificates
proxy.WithTlsConfig(&tls.Config{
InsecureSkipVerify: true,
})
// Create a fake server for handling the proxied request
_, addr := createProxyTestServer(
func(c *fiber.Ctx) error {
return c.SendString("forwarded")
}, t, "/events/bulk/:id",
)
// Mock out the function that returns config - there must be a better way
// Adjust the config so that we're forwarding requests to our new server
cfg = func() config.Config {
return config.Config{
Proxy: config.Proxy{
Forward: config.Forward{
Events: addr,
},
},
}
}
// Set up the route, and specify the handler under test
app.Post("/events/bulk/:id", BulkEventsHandler)
// Create some dummy event data
bodyReader := strings.NewReader(`{"user": "12124", "data": "blah"}`)
// Test our proxy
resp, err := app.Test(
httptest.NewRequest(
"POST",
"/events/bulk/1234",
bodyReader,
),
)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusOK, resp.StatusCode)
b, err := ioutil.ReadAll(resp.Body)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "forwarded", string(b))
}
Is the following necessary? Should I instead somehow mock proxy.Do?
Server that handles the proxied request
func createProxyTestServer(handler fiber.Handler, t *testing.T, path string) (*fiber.App, string) {
// Helper marks the calling function as a test helper function.
t.Helper()
// Create a new fiber app that will act as the server
target := fiber.New(fiber.Config{DisableStartupMessage: true})
// Set up the route that we will expect to be proxied to us
target.Post(path, handler)
// Create a listener on a random unused port
ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0")
utils.AssertEqual(t, nil, err)
// Generate self-signed certs for this server
serverTLSConf, _, err := getTLSConfigs()
utils.AssertEqual(t, nil, err)
// Update the listener with the certs
ln = tls.NewListener(ln, serverTLSConf)
// This has to be run in a goroutine otherwise it will block
go func() {
// set the app's listener
utils.AssertEqual(t, nil, target.Listener(ln))
}()
// Give the app time to get ready - this isn't ideal
time.Sleep(2 * time.Second)
addr := ln.Addr().String()
return target, addr
}
Additionally, I'd like to test that the saveEvent method in my handler gets called, but the only way I think I could do that is if I altered the call signature of the handler e.g. func(c * fiber.Ctx, db *DB) where I could pass in a mock instead. But I don't think that is possible. Any recommendation would be most welcome. Thank you.
Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord
Question description Hi there, thank you for the awesome Gofiber package. I have a question about testing Gofiber as a proxy. Small caveat: I am somewhat new to Go and Gofiber.
I have implemented a small proxy service using Gofiber, and I used your tests here as reference for writing my own tests.
I'd like to know if this the recommend or correct approach to testing Gofiber as a proxy? Or if I should be mocking out the proxying somehow.
Handler Function
TestFunction
Is the following necessary? Should I instead somehow mock
proxy.Do
?Server that handles the proxied request
Additionally, I'd like to test that the
saveEvent
method in my handler gets called, but the only way I think I could do that is if I altered the call signature of the handler e.g.func(c * fiber.Ctx, db *DB)
where I could pass in a mock instead. But I don't think that is possible. Any recommendation would be most welcome. Thank you.