Form variables are not available in tests

PHPz
Release: 2024-02-06 08:09:07
forward
413 people have browsed it

Form variables are not available in tests

Question content

I am new to Go. I wrote an API server built on top of the Echo server using the DeepMap OpenAPI generator and Postgres using pgxpool. It works fine and is a year old, but that doesn't mean it's written correctly :).

The test server has been using a shell script and a series of Curl calls, which works great, but I'm trying to update the tests to use Go's testing framework. I've done some basic testing, but anything that requires form values ​​doesn't work - the handler function doesn't see any form values, so I'm guessing the request isn't encapsulating them, but I don't understand why.

The following is the first part of the CreateNode() method, which implements part of the generated API interface. I've omitted the body; the failing part is what appears in context.

func (si *ServerImplementation) CreateNode(ctx echo.Context) error {
        vals, err := ctx.FormParams()
        info("In CreateNode() with FormParams %v", vals)
        ...
Copy after login

This is the test function:

func TestCreateNode(t *testing.T) {
        // not the actual expected return
        expected := "Node created, hooray\n"

        // initialize database with current schema
        api := &ServerImplementation{}
        err := api.Init("host=localhost database=pgx_test user=postgres")
        if err != nil {
                t.Fatal(err)
        }

        // handle teardown in this deferred function
        t.Cleanup(func() {
                t.Log("Cleaning up API")
                api.Close()
        })

        // start up webserver
        e := echo.New()

        // this didn't work either
        //f := make(url.Values)
        //f.Set("name", "node1")
        //req := httptest.NewRequest(http.MethodPost, "/nodes/", strings.NewReader(f.Encode()))
        //req.Header.Add("Content-Type", "multipart/form-data")

        req := httptest.NewRequest(echo.POST, "/", strings.NewReader(`{"name":"node1"}`))
        req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
        rec := httptest.NewRecorder()
        ctx := e.NewContext(req, rec)

        if assert.NoError(t, api.CreateNode(ctx)) {
                assert.Equal(t, http.StatusOK, rec.Code)
                assert.Equal(t, expected, rec.Body.String())
        }
}
Copy after login

I won't bother with the full test output, because when CreateNode() receives no value, everything fails:

=== RUN   TestCreateNode
2023/08/26 15:09:43 INFO:    In CreateNode() with FormParams map[]
2023/08/26 15:09:43 INFO:    No name provided in CreateNode()
Copy after login

As far as I know, I'm following similar examples closely. I hope this is enough detail, but don't want to overload the issue with unnecessary support code.

The endpoint for

nodes is /nodes and the base URL for the API is /api, but neither of those are reflected here, from the examples I've seen of them is unnecessary. Echo's examples always use / as endpoints.


Correct answer


Okay, I am Ding Dong.

I've cobbled together a lot of examples trying to get something to work, and only once did I try the following in a test function:

req.Header.Set("Testing", "Yes")
Copy after login

and pop it in CreateNode:

info("Header: %v", ctx.Request().Header)
Copy after login

This gives me:

2023/08/26 20:04:36 INFO:    Header: map[Content-Type:[application/x-www-form-urlencoded] Testing:[Yes]]
Copy after login

I see that the request is going well, it has to do with the way I formed the request.

I checked the examples again and realized that I was setting the form value based on one example but setting the content type from another example. The works are as follows:

f := make(url.Values)
        f.Set("name", "node1")
        req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(f.Encode()))
        req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm)
Copy after login

Of course, doing this via JSON won't work because that's not how CreateNode() parses the incoming information.

This is just my carelessness!

The above is the detailed content of Form variables are not available in tests. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template