Search code examples
rubyapitestunitvcrwebmock

Ruby TestUnit, VCR and HTTP API Requests


I am building an API wrapper and am writing some tests for it and I have a couple of questions.

1) How do I write an assert for calls where data doesn't exist? For example, looking up a member by id using the API but the user won't exist yet.
2) How do I write an assert for testing PUT and DELETE requests?

I already have a grasp on testing GET and POST requests just not sure on the other 2 verbs.


Solution

  • For your question part 1...

    You have a couple choices for data that doesn't exist:

    1. You can create the data ahead of time, for example by using a test seed file, or a fixture, or a factory. I like this choice for larger projects with more sophisticated data arrangements. I also like this choice for getting things working first because it's more straightfoward to see the data.

    2. You can create a test double, such as a stub method or fake object. I like this choice for fastest test performance and best isolation. For fastest tests, I intercept calls as early as possible. The tradeoff is that I'm not doing end-to-end testing.

    For your question part 2...

    You should edit your question to show your actual code; this will help people here answer you.

    Is your VCR code is something like this?

    VCR.use_cassette('test_unit_example') do
      response = Net::HTTP.get_response('localhost', '/', 7777)
      assert_equal "Hello", response.body
    end
    

    If so, you change the HTTP get to put, something like this:

    uri = URI.parse(...whatever you want...)
    json = "...whatever you want..."
    req = Net::HTTP::Put.new(uri)
    req["content-type"] = "application/json"
    req.body = json
    request(req)
    

    Same for HTTP delete:

    Net::HTTP::Delete.new(uri)
    

    A good blog post is the http://www.rubyinside.com/nethttp-cheat-sheet-2940.html>Net::HTTP cheat sheet excerpted here:

    # Basic REST.
    # Most REST APIs will set semantic values in response.body and response.code.
    require "net/http"
    
    http = Net::HTTP.new("api.restsite.com")
    
    request = Net::HTTP::Post.new("/users")
    request.set_form_data({"users[login]" => "quentin"})
    response = http.request(request)
    # Use nokogiri, hpricot, etc to parse response.body.
    
    request = Net::HTTP::Get.new("/users/1")
    response = http.request(request)
    # As with POST, the data is in response.body.
    
    request = Net::HTTP::Put.new("/users/1")
    request.set_form_data({"users[login]" => "changed"})
    response = http.request(request)
    
    request = Net::HTTP::Delete.new("/users/1")
    response = http.request(request)