# Unit-testing HTTP handlers

**URL:** <https://forum.crystal-lang.org/t/unit-testing-http-handlers/1065>\
**Category:** Help & Support\
**Created:** [August 24, 2019, 2:28am UTC](https://forum.crystal-lang.org/t/unit-testing-http-handlers/1065 "2019-08-24T02:28:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [August 24, 2019, 2:28am UTC](https://forum.crystal-lang.org/t/unit-testing-http-handlers/1065/1 "2019-08-24T02:28:42Z")

</div>

I’m trying to build a simple JSON service that routes like Roda to `HTTP::Handler`-like instances:

```crystal
class App
  include HTTP::Handler
  include Routing

  def call(context)
    route context do |r, response, session|
      r.root { HomePage.new.call context }

      r.on "api" { API.new.call context }

      # other routes...
    end
  end
end

```

Since it’s just passing off the context, I’m looking for a way to unit-test these individual routes, building up the `HTTP::Server::Context` myself and stubbing out other services. Unfortunately, when I parse the response in this spec:

```crystal
describe "GET /people" do
  it "returns a list of people" do
    io = IO::Memory.new
    response = HTTP::Server::Response.new io
    context = HTTP::Server::Context.new(
      request: HTTP::Request.new("GET", "/people"),
      response: response,
    )
    response.flush

    ExampleWebService::App.new.call context

    io.rewind.to_s STDOUT
    response_body = JSON.parse(io.rewind)
    response_body.should eq({
      people: [
        { id: 123, name: "Jamie" },
      ],
    })
  end
end

```

The response `IO` is empty, so I get a JSON parsing error in the spec. This is the code:

```crystal
module ExampleWebService
  class App
    include HTTP::Handler

    def call(context)
      {
        people: [
          Person.new(id: 123, name: "Jamie"),
        ],
      }.to_json context.response
    end
  end

```

It’s all hardcoded right now while I flesh out the pattern of unit-testing it, so there’s nothing really to go wrong. When I run it through an `HTTP::Server`, it works just fine, it just seems like the data isn’t making it to the `IO` instance inside the spec. I’m using `response.flush`, is there something else I need to be doing there?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [August 24, 2019, 3:17am UTC](https://forum.crystal-lang.org/t/unit-testing-http-handlers/1065/2 "2019-08-24T03:17:36Z")

</div>

I think you want to flush the response _after_ executing the handler. Then you get

```auto
HTTP/1.1 200 OK
Transfer-Encoding: chunked

26
{"people":[{"id":123,"name":"Jamie"}]}

```

which still fails since there is other data.

---

<div class="post-metadata">

**Author:** ![jgaskins](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jgaskins/32/2449_2.png) [@jgaskins](https://forum.crystal-lang.org/u/jgaskins)\
**Post date:** [August 24, 2019, 3:34am UTC](https://forum.crystal-lang.org/t/unit-testing-http-handlers/1065/3 "2019-08-24T03:34:13Z")

</div>

OMG, you’re right. Man, I was staring at this until I was questioning whether I knew how computers worked. 😝

I can handle it from there, I think. I just didn’t realize I put the flush in the wrong place. Thanks!
