VividCortex / siesta

Composable framework for writing HTTP handlers in Go.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pull testing code into siesta?

JnBrymn opened this issue · comments

I tend to think that a test harnesses should be placed with the library you're. In this case consider:

  1. Sticking the fake context into siesta so that users don't have to recreate it. ... Though arguable this is simple enough not to matter too much.
  2. I haven't found anything yet that allows me to test out the routes themselves. I wonder what would be a good method for that? Perhaps replace all handlers with test handler?
  1. We could just make a NewSiestaContext() that returns a blank context. There's something like that right now but it's not exported.
  2. Not sure what you mean. Are you thinking about testing the routing itself, or testing individual handlers?
  1. Yep, that'll probably do. Though there's less likely case that you want some test code as a callback in the Set or Get methods - but this is simple enough to write that it probably doesn't belong in siesta itself.
  2. Yep, test the routing itself. I had a silly route typo today that I puzzled over for 30 minutes. In the future it would be nice to know when such breaking errors are introduced. Though I haven't thought a lot about how I would make an elegant solution here.

Well, our routing is not deterministic right now so it's more difficult to test. Maybe we can borrow a better router from tigertonic or Goji.

Bullet 1 fixed in #7

Here's a good example test. As it is now:

func TestMySqlErrorLookup(t *testing.T) {
    c := siesta.NewSiestaContext()
    request, err := http.NewRequest("GET", "lookup/error?q=123,9999999,124", nil)
    request.ParseForm()
    if err != nil {
        t.Fatal("couldn't create request", err)
    }
    GetError(c, nil, request, func() { t.Error("should be no reason to quit") })
    shouldBe := map[string]interface{}{"data": []string{"Someone has changed the row since it was read (while the table was locked to prevent it)", "Illegal error code: 9999999", "Wrong index given to function"}}
    is := c.Get("response")
    if !reflect.DeepEqual(is, shouldBe) {
        t.Error(is, "is not", shouldBe)
    }
}

I wish it was more like this

func TestMySqlErrorLookup(t *testing.T) {
    c := siesta.NewSiestaContext()
    setUpRounting() //this would be run in my main func, but also in test.
    siesta.TestEndpoint("GET", "lookup/error?q=123,9999999,124", c)
    shouldBe := map[string]interface{}{"data": []string{"Someone has changed the row since it was read (while the table was locked to prevent it)", "Illegal error code: 9999999", "Wrong index given to function"}}
    is := c.Get("response")
    if !reflect.DeepEqual(is, shouldBe) {
        t.Error(is, "is not", shouldBe)
    }
}

@PreetamJinka I would like to use this now as I write tests for api-lookup. Do you mind recommending api and functionality here so that I can implement it? Otherwise nix it and I'll just stick with the long version of the tests.

My thoughts:

// Usage: siesta.TestRoute("GET", "fruit/4?color=red", []byte("Hello Clarice"), myContext, myHttpResponseWriter)
func (s *Service) TestRoute(verb,url string, requestBody []byte, c Context, w http.ResponseWriter) {...}

What I'm trying to do here is to a) test routes and b) not have to do this every time

...
    request, err := http.NewRequest("GET", "lookup/error?q=123,9999999,124", nil)
    request.ParseForm()
    if err != nil {
        t.Fatal("couldn't create request", err)
    }
    GetError(c, nil, request, func() { t.Error("should be no reason to quit") })
...

The one kinda yucky thing is that you have to provide a http.ResponseWriter, so maybe create a siesta.TestResponseWriter that implements the interface and adds a Read() []bytes method so that we can actually see what was written. Most of the time the user will use siesta to write to the http.ResponseWriter so we'll only need the Context.

Oh... and make recommendations on code organization. Is util.go ok? Want a sub package?

I don't see why all that belongs in this package. Those testing helpers belong with the program you're writing. Your TestEndpoint is an example of that. I think any code related to testing in this package should be for testing this package itself.

FYI there are plenty of examples available elsewhere of how to set up HTTP tests.

Fair enough, I can stick this function in my repo... but I think I would like to have it in every repo where I use siesta, which is why I think that general test helpers belong in the repo.

The last few comments address item 2 from the initial post. Closing.