1

Below is my code for main.go

func main() {
    app := fiber.New()

    app.Use(recover.New())
    inferenceController := controllers.InferenceController
    middleware := middleware.Middleware

    privateRoutes := routes.PrivateRoutes{InferenceController: inferenceController,Middleware: middleware }
    privateRoutes.Routes(app)

    log.Fatal(app.Listen(":3000"))
}

I am trying to test this code but can't figure out the way for testing

Taha Khan
  • 69
  • 5
  • Which part you want to test? I think you can be inspired by [app_test.go from Fiber](https://github.com/gofiber/fiber/blob/master/app_test.go) – spike014 Dec 08 '22 at 01:51
  • And [route_test.go from Fiber](https://github.com/gofiber/fiber/blob/master/router_test.go) – spike014 Dec 08 '22 at 01:52
  • I have written routers and middlewares test now I want to test the main function of the application – Taha Khan Dec 08 '22 at 06:28

1 Answers1

1

In your test you actually need to create the app and register the relevent handlers. Then use app.Test() to call the handler. You can create body content as needed and check response codes and body content.

In this model you setup your server with just the endpoints/middleware you need for each test case. You can provide mock's around this if you need, depending on your specific use case.

For your example above, it would be something like the below, not knowing what your actual endpoints are:

func TestMyFiberEndpoiunt(t *testing.T) {
    // Setup the app
    app := Fiber.New()
    app.Use(recover.New())
    inferenceController := controllers.InferenceController
    middleware := middleware.Middleware
    privateRoutes := routes.PrivateRoutes{InferenceController: inferenceController,Middleware: middleware }
    privateRoutes.Routes(app)

    // Setup your request body
    reqBody := ReqData{ SomeData: "something" }
    bodyJson, _ := json.Marshal(&reqBody)
    req := httptest.NewRequest("GET", "/api/v1/endpoint", bytes.NewReader(bodyJson))
    resp, _ := app.Test(req, 10)

    // Check the expected response code
    assert.Equal(t, 200, resp.StatusCode)

    // Check the body content
    respBody := make(byte, resp.ContentLength)
    _, _ = resp.Body.read(respBody)
    assert.Equal(t, `{"data":"expected"}`, string(respBody))
}

If you need stateful data accross multiple tests for some use case, you could setup your server in a TestMain with all the needed routes and share it as a package var.

If the data marshalling seems like a lot of overhead for each test case, you can use a helper function such as:

func GetJsonTestRequestResponse(app *fiber.App, method string, url string, reqBody any) (code int, respBody map[string]any, err error) {
    bodyJson := []byte("")
    if reqBody != nil {
        bodyJson, _ := json.Marshal(reqBody)
    }
    req := httptest.NewRequest(method, url, bytes.NewReader(bodyJson))
    resp, err := app.Test(req, 10)
    code = resp.StatusCode
    // If error we're done
    if err != nil {
        return
    }
    // If no body content, we're done
    if resp.ContentLength == 0 {
        return
    }
    bodyData := make([]byte, resp.ContentLength)
    _, _ = resp.Body.Read(bodyData)
    err = json.Unmarshal(bodyData, &respBody)
    return
}

Then tests cases look cleaner and are easier to write (imho).

type testArg struct {
    Arg1 string
    Arg2 int
}

func TestMyFakeEndpoint(t *testing.T) {
    app := fiber.New()
    defer app.Shutdown()    
    app.Post("/test", func(c *fiber.Ctx) error {
        arg := testArg{}
        _ = json.Unmarshal(c.Request().Body(), &arg)
        return c.JSON(arg)
    })

    code, body, err := GetJsonTestRequestResponse(app, "POST", "/test", testArg{"testing", 123})
    assert.Nil(t, err)
    assert.Equal(t, 200, code)
    assert.EqualValues(t, body["Arg1"], "testing")
    assert.EqualValues(t, body["Arg2"], 123)
}
pilotpin
  • 137
  • 5