4

I am building a Ruby command-line program that communicates with a web service. I am using Cucumber and Aruba to test the program. The problem is that I need to control the data returned from the web service; the program grabs a stream of user comments, so this can change frequently as new comments are added. I tried to mock the web service using WebMock, but this didn't work, since Aruba spins the command-line program off into a separate process that is unaffected by WebMock (so it still communicated with the real web service).

How can I test the output of this program using Cucumber?


Edit: The web service returns the stream as JSON data. I've captured a snapshot of data to use for testing; in a nutshell, I'm looking for a way to substitute my static data in place of an actual call to the web service.

Or, if there's a completely different way to accomplish this goal, I'm all ears.

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • If everything else fails, you should be able to redirect to requests via your `hosts` file to a local webservice that serves the captured JSON data. But I hope someone can come up with a better solution than this :) – doesterr Dec 04 '12 at 23:23
  • @doesterr: Haha, yeah, I'd considered that. But I don't know if I can expect other people who might want or need to test it to also do that. ;) – mipadi Dec 04 '12 at 23:26
  • right, it's a last resort "solution" :) – doesterr Dec 05 '12 at 14:17

3 Answers3

1

Aruba provides a mode that lets you run things "in process" that will allow you to use WebMock or VCR. Here's a blog post explaining how to do that:

http://georgemcintosh.com/vcr-and-aruba/

Alternately, you can consider writing a new binary that first loads VCR or WebMock, and then loads and executes your main binary, and have your test run this binary.

Myron Marston
  • 21,452
  • 5
  • 64
  • 63
0

You could use vcr (cf. https://github.com/vcr/vcr)

It will turn your json response into a fixture.

I will copy the beginning of their Readme so you can get the idea:


require 'rubygems'
require 'test/unit'
require 'vcr'

VCR.configure do |c|
  c.cassette_library_dir = 'fixtures/vcr_cassettes'
  c.hook_into :webmock # or :fakeweb
end

class VCRTest < Test::Unit::TestCase
  def test_example_dot_com
    VCR.use_cassette('synopsis') do
      response = Net::HTTP.get_response(URI('http://www.iana.org/domains/reserved'))
      assert_match /Example domains/, response.body
    end
  end
end

Run this test once, and VCR will record the http request to fixtures/vcr_cassettes/synopsis.yml. Run it again, and VCR will replay the response from iana.org when the http request is made. This test is now fast (no real HTTP requests are made anymore), deterministic (the test will continue to pass, even if you are offline, or iana.org goes down for maintenance) and accurate (the response will contain the same headers and body you get from a real request).

Aitherios
  • 96
  • 2
-1

Command line programs take parameters, so I'd write the program to take a URL as an arg that points to whatever service you want. Then I'd make a test version of your web service, using seed data that doesn't change. Then I'd write the cucumber tests to call the program with the test URL, and test against the expected data.

LazyMonkey
  • 517
  • 5
  • 8
  • The web service is actually called through a third-party library; changing the URL isn't an option. – mipadi Dec 04 '12 at 22:45
  • Does the comment stream contain any metadata? Something like a datetime (or part thereof) could be tested for, I should think. – LazyMonkey Dec 04 '12 at 23:08
  • It comes back as a JSON feed; I have captured one such response to a file, I'm just looking for a way to substitute my static data in place of an actual call to the web service. – mipadi Dec 04 '12 at 23:13